Question about the efficiency of using an array or individual variables

In summary, the conversation discusses the efficiency of using array A[10] versus individual variables B(0..9) in a program. The individual variables may be faster due to their one-step access, while the array requires additional steps to access the desired value. The conversation also touches on the limitations of declaring arrays with a constant size and the use of vector as a workaround. Finally, the conversation explains the difference in initialization between {1} and {1, 1, 1, 1, 1, 1, 1, 1, 1, 1} for an array of boolean values.
  • #211
It's worth mentioning that one application of double indirection is a binary search of an ordered list. A function that is passed two pointers to different locations in the list can find the midpoint of the list, and determine whether the search target is in one or the other half of the list. The function can modify one of the passed pointers, and then call itself recursively to resume the search.

This is one of the things that you would learn in studying data structures and algorithms.
 
  • Like
Likes yungman
Technology news on Phys.org
  • #212
Hi Mark44

Thank you so much to have the patience to explain these. I actually copied your last few posts and print it out to read line by line and correct my notes. Still working on these. Just want to acknowledge you first, I'll be back.
 
  • #213
Hi

I am still going through the chapter, I even read the chapter of pointers from my former book to look at another perspective. I have a program that runs. I just want to verify whether I am correct:
C++:
// Dynamic memory with pointer in function
#include <iostream>
using namespace std;
void getValue(int**, int);// function receive pointer to a pointer.

int main()
{
    int count, size = 5;
    int* ptr;// Initialize point ptr.
    getValue(&ptr, size); // Pass the ADDRESS of pointer ptr.
    cout << " Back in main, array pointed by ptr = {";
    for (count = 0; count < (size - 1); count++)
    {
        cout << *(ptr + count) << " ";
    }
    cout << *(ptr + (size - 1)) << " }\n\n";
    delete[] ptr;
    return 0;
}
void getValue(int** pt, int size)//receive pointer to pointer pt.
{
    int count;
    int *Ar = new int[size];//Ar is a pointer to allocate memory
                            //Ar is the address of the first element
    for (count = 0; count < size; count++)
    {
        cout << " Enter number " << (count + 1) << " = ";
        cin >> *(Ar + count); cout << "\n";
    }
    *pt = Ar;//pt is a pointer to pointer, *pt dereference pt which is a pointer.
    cout << " In getValue, array pointed by pt = {";
    for (count = 0; count < (size - 1); count++)
    {
        cout << *(*pt + count) << " ";// first * dereference, *pt is address of the start of array.
                                      // count is to go the number of element down from first element.
    }
    cout << *(*pt + (size - 1)) << " }\n\n";
}

I want to verify whether my understanding is correct
1) when declare int**pt. This declare pt is a pointer to pointer. In line 30, *pt means dereference the pointer-to-pointer ptr, which give the address of the int variable that it is pointing to(in this case is the first element of the 5 element memory). in another words, '*' is dereference of ( pointer-to-pointer ptr).

2) Line 34, *(*pt + count) means dereferencing (*pt+count ). (*pt+count ) is the address of the first element of the memory + number of elements down in address(count). eg, if count =2, then (*pt + count) points to the 3rd element of the memory.

3) Line 10: getValue(&ptr, size) is to pass the ADDRESS of the pointer ptr to the function. Which is the same kind as pointer to a pointer declared in the function.

4) Line 14, *(ptr + count) is dereference (ptr + count). ptr is a pointer to the first element of the memory allocated. (ptr + count) points the the number of elements down from the first element specified by count.

I hope I got these correct, please let me know.

My biggest confusion is for int**pt, pt without any '*' actually mean pt is a pointer-to-pointer variable. The *pt is DEREFERENCING the pointer-to-pointer pt. Which is the address it's pointing to.
 
  • #214
Your program looks pretty good, but there are a couple of very minor nits.
Line 8: count is a misleading name. You're actually using it as an index in your array. The name i would be perfectly fine in this case, or idx, or index.

Line 9: int* ptr;// Initialize point ptr.
The comment is not correct. All that's happening here is that ptr is being declared, not initialized. When a variable is initialized, it is given a value. At this point ptr contains some random address.

yungman said:
1) when declare int**pt. This declare pt is a pointer to pointer. In line 30, *pt means dereference the pointer-to-pointer ptr, which give the address of the int variable that it is pointing to(in this case is the first element of the 5 element memory). in another words, '*' is dereference of ( pointer-to-pointer ptr).
Yes. To help you out, think of the declaration int**pt in two parts -- the type being declared: int**, pointer to pointer to int, and the name for that type: pt. It's important to keep in mind the type that the pointers ultimately point to - omitting this was the source of much confusion for you earlier.

After the name ptr has been declared, you can dereference it once or twice.
ptr -- pointer to pointer to an int (i.e., the address of the address of an int)
*ptr - pointer to an int (i.e., the address of an int)
**ptr - the int being pointed to.
See the drawing I attached in post #210.
yungman said:
2) Line 34, *(*pt + count) means dereferencing (*pt+count ). (*pt+count ) is the address of the first element of the memory + number of elements down in address(count). eg, if count =2, then (*pt + count) points to the 3rd element of the memory.
Yes, although as mentioned already, I would write this as *(*pt + index) or similar name.
It's important to understand that pointer arithmetic is being used here, so if index happens to be 2, for example, the above actually adds 8 (= 2 * sizeof(int)) to the address in *pt.
yungman said:
3) Line 10: getValue(&ptr, size) is to pass the ADDRESS of the pointer ptr to the function. Which is the same kind as pointer to a pointer declared in the function.
Right
yungman said:
4) Line 14, *(ptr + count) is dereference (ptr + count). ptr is a pointer to the first element of the memory allocated. (ptr + count) points the the number of elements down from the first element specified by count.
Yes.
yungman said:
My biggest confusion is for int**pt, pt without any '*' actually mean pt is a pointer-to-pointer variable.
See my explanation in item 1.
 
  • Like
Likes yungman
  • #215
Thank you Mark44. I spent two days reading from another book, copied your response and read them line by line. I think I finally got it. It is very tricky, it's the names and meaning of symbols that tricked me. It's so easy to interpret it wrong and they work "most" of the time, so close but totally wrong. I even copied your program and called it Mark44 to play with it and add something more in it.
C++:
//Mark44 pointers
#include <iostream>
using namespace std;

void passAddr(int**);
int main()
{
    int List[] = { 1, 3, 5, 7, 9 };
    int* ptr;                   // Initialize ptr with the address of List, which is itself a kind of pointer.
    ptr = List;
    cout << " address of ptr = " << ptr << "\n\n";
    cout << "Before call to passAddr(), *ptr == " << *ptr << "\n\n";
    passAddr(&ptr);                // Pass the address of the pointer to the first element of the array.
    cout << "After call to passAddr(), *ptr == " << *ptr << "       *(List + 2) = " << *(List + 2) << "\n\n";
    ptr = ptr + 2; // from passAddr() and ptr +2, total is ptr + 4. therefore *ptr = 9
    cout << "After ptr = ptr + 2, *ptr == " << *ptr << "\n\n";

    char vec = 'A';
    char* ptc; ptc = &vec;
    cout << " *ptc = " << *ptc << "    ptc = " << ptc << "   &vec = " << &vec << "\n\n";
    // somehow, cout << ptc and cout &vec give funny display.
    return 0;
}

void passAddr(int** pptr)
{
    cout << " address of pptr = " << pptr << " *pptr = " << *pptr << "\n\n";
    *pptr += 2;   // pptr is a pointer to a pointer. *pptr = address of first element of array
                  // +2 move pptr to point to 3rd element of array
    cout << " **pptr = " << **pptr << "\n\n";// after *pptr +=2, **pptr = *(*pptr) = 5, double indirection
}

Attached is my corrected notes on Chapter 9.

Well, I want to stimulate my mind studying C++, this sure shake out a lot of rust! I am glad to pick learning computer language instead of staying in the comfort zone of electronics. No matter what project I pick to do in electronics, it's just add onto the experience, it doesn't really challenge the mind. This is turning everything up side down and really shake it up.

I believe that it's very important as I get old to keep both my mind and body in shape. You don't use it, you lose it. The older you get, the faster you lose it and you need to work harder to keep it. I spend a lot of time on both now a days, no point of living long if I am disable and lost my mind. This is my way of keeping young! 😊 o_O
 

Attachments

  • Gaddis notes.docx
    69 KB · Views: 126
  • #216
yungman said:
I believe that it's very important as I get old to keep both my mind and body in shape.
Absolutely. Part of the reason I'm still teaching is to help keep my mind in shape. And I still regularly go on strenuous backpack trips even though I just turned 76.

Here are a few comments on your code.
Lines 9 and 10:
int* ptr; // Initialize ptr with the address of List, which is itself a kind of pointer.
ptr = List;
The above is fine, but instead of doing a declaration (line 9) followed by an assignment (line 10), you could do it with a definition (declaration + initialization), like this:
C++:
int* ptr = List;

Same for line line 19, which you could do like this:
C++:
char* ptc = &vec;

In line 21 you have this comment:
Code:
// somehow, cout << ptc and cout &vec give funny display.

You asked about this before. It's because the << operator assumes from your declarations, that *ptc and &vec are not just single characters, but the first characters of C-style strings. However, they are not C-style strings because they aren't null-terminated. When inserted into the cout stream, you get the first character plus all the characters until a null is encountered.
 
  • Like
Likes yungman
  • #217
If you want to use the C way to print, you can do this:
C:
#include <cstdio>
int main() {
    const char * cs = "hello";
    std::printf( "%p \n", cs ); // %p is a placeholder with format specifier to print as a pointer, \n means newline
    std::printf( "%s \n", cs ); // %s specifies print as a c-string
}

It's probably more common to print c-strings than char pointers, and C++ hides the format specifier which would let you differentiate.
 
  • #218
Mark44 said:
Absolutely. Part of the reason I'm still teaching is to help keep my mind in shape. And I still regularly go on strenuous backpack trips even though I just turned 76.

Here are a few comments on your code.
Lines 9 and 10:

The above is fine, but instead of doing a declaration (line 9) followed by an assignment (line 10), you could do it with a definition (declaration + initialization), like this:
C++:
int* ptr = List;

Same for line line 19, which you could do like this:
C++:
char* ptc = &vec;

In line 21 you have this comment:
Code:
// somehow, cout << ptc and cout &vec give funny display.

You asked about this before. It's because the << operator assumes from your declarations, that *ptc and &vec are not just single characters, but the first characters of C-style strings. However, they are not C-style strings because they aren't null-terminated. When inserted into the cout stream, you get the first character plus all the characters until a null is encountered.
Thanks for the reply.
I thought even though declaration char*ptc, ptc and &vec are all addresses that can be displayed as Hex.

Good for you in staying active physically too. It makes a huge difference. People are like cars, when the car is new, it can take a lot of neglect and it will run perfect for a few years, but after 5 or 6 years, everything will catch up. A 40 years old car can run like new if it is well maintained. Me and my wife spend a lot of time exercise in the gym, she is 75, she just had the second hip replaced 3 weeks ago, she's off the cain, up and down the stairs and out shopping already. It's because she is in shape. She like to walk, that really did her in on her hips, her walk was like slow jogging and she walk 2 miles 6days a week. That's why she had two hip replacement...Too much of a good thing! Kept telling her don't do it 6 days a week, she didn't listen. As I get old, I do it hard, but with plenty of rest in between. 2 days of weight lifting and 2 days of kick boxing on heavy bags at home, with plenty of rest in between...Now is C++ for the brain! good thing with the brain, it doesn't need rest and day off.
 
  • #219
Jarvis323 said:
If you want to use the C way to print, you can do this:
C:
#include <cstdio>
int main() {
    const char * cs = "hello";
    std::printf( "%p \n", cs ); // %p is a placeholder with format specifier to print as a pointer, \n means newline
    std::printf( "%s \n", cs ); // %s specifies print as a c-string
}

It's probably more common to print c-strings than char pointers, and C++ hides the format specifier which would let you differentiate.
thanks, I have not learn this yet. I'll learn it when the time comes.
Now I move on to chapter 10, characters, strings. the Character part is so boring! Checking inalpha, inlower, indigit.....I am falling asleep just typing the program!

I am sighting myself up to go through how to change from lower case to upper case! That's the reason I am here shooting the breeze instead of working on the program!
 
  • #220
yungman said:
Checking inalpha, inlower, indigit
These are actually isalpha(), islower(), isdigit() and so on. They are all holdovers from C, where their declarations were in ctype.h
yungman said:
I am sighting myself up to go through how to change from lower case to upper case!
That's easy to do without any library functions. To convert from lower case to upper case, just subtract 32 from each character's ASCII code. To go the other way, from upper case to lower case, just add 32.

Of course, this assumes that you're using the code page for English, and one-byte characters. Changing from upper- to lower case in other languages (and code pages) and vice-versa is more complicated.
 
  • Like
Likes yungman
  • #221
I am glad those upper and lower case stuffs only lasted 5 or 6 pages. I am moving onto String Literal, C-Strings. I have a question I am no able to nail it. What is String Literal and C string?
C++:
#include <iostream>
#include<cstring>
using namespace std;

int main()
{
    char St[] = "This is a test";//String Literal,  length = 15
    cout << " Enter sentence: ";  cin.get(St, 15);//can have space.
    cout << St << "\n\n";
    return 0;
}

You see I declare and initialized a String Literal with "This is a test". BUT as you see, I can change the sentence as long as I don't get over 14 characters ( + '\0'). What is the point of String Literal, I might as well declare St[20] = {'\0'} and then cin.get(St, 20) to put in the sentence. Only thing advantage is you can use cout << "This is a test"; that doesn't involve one extra array St[].

I am still looking for difference between cin.get(St,20) vs cin.getline(St,20). They work same so far for me.

Thanks
 
  • #222
yungman said:
I am glad those upper and lower case stuffs only lasted 5 or 6 pages. I am moving onto String Literal, C-Strings. I have a question I am no able to nail it. What is String Literal and C string?
A string literal is an array of characters surrounded by double quotes -- e.g., "This is a test" is a string literal. The word literal is a synonym of constant.
A C-string is a null terminated array of characters.
yungman said:
C++:
#include <iostream>
#include<cstring>
using namespace std;

int main()
{
    char St[] = "This is a test";//String Literal,  length = 15
    cout << " Enter sentence: ";  cin.get(St, 15);//can have space.
    cout << St << "\n\n";
    return 0;
}

You see I declare and initialized a String Literal with "This is a test". BUT as you see, I can change the sentence as long as I don't get over 14 characters ( + '\0'). What is the point of String Literal, I might as well declare St[20] = {'\0'} and then cin.get(St, 20) to put in the sentence. Only thing advantage is you can use cout << "This is a test"; that doesn't involve one extra array St[].
There's no point in initializing St.
It would be clearer to do this:
C++:
char St[15];
cout << " Enter sentence of 14 or fewer characters: "; 
cin.get(St, 15);//can have space.
yungman said:
I am still looking for difference between cin.get(St,20) vs cin.getline(St,20). They work same so far for me.
Both functions have multiple overloads, with six overloads for get() and two overloads for getline(). The basic difference between the two as I understand things is that get() doesn't store the termination character (which you can specify), while getline() does store this character.

By default, the termination character is \n, but you can specify something different as a 3rd parameter in either function.

See https://docs.microsoft.com/en-us/cpp/standard-library/basic-istream-class?view=vs-2019#get for the documentation for get(), and immediately after that on the same page for the docs for getline().
 
Last edited:
  • Like
Likes yungman
  • #223
Mark44 said:
A string literal is an array of characters surrounded by double quotes -- e.g., "This is a test" is a string literal. The word literal is a synonym of constant.
A C-string is a null terminated array of characters.
There's no point in initializing St.
It would be clearer to do this:
C++:
char St[15];
cout << " Enter sentence of 14 or fewer characters: ";
cin.get(St, 15);//can have space.
yungman said:
I am still looking for difference between cin.get(St,20) vs cin.getline(St,20). They work same so far for me.
Both functions have multiple overloads, with six overloads for get() and two overloads for getline(). The basic difference between the two as I understand things is that get() doesn't store the termination character (which you can specify), while getline() does store this character.

By default, the termination character is \n, but you can specify something different as a 3rd parameter in either function.

See https://docs.microsoft.com/en-us/cpp/standard-library/basic-istream-class?view=vs-2019#get for the documentation for get(), and immediately after that on the same page for the docs for getline().
I have to fix your post to be readable, I don't understand what is overload and when I follow the link, I have not learn istream yet, so the link doesn't help me in understand better.
 
Last edited by a moderator:
  • #224
yungman said:
I have to fix your post to be readable
I put in a quote end tag where I should have put in a code end tag. I've fixed things in my post and in what you quoted.
yungman said:
I don't understand what is overload
In C++, but not C, you can have multiple functions with the same name, but with different sets of arguments. For example, you could have multiple functions named print, with each designed to print a different type of value.
C++:
void print(int val);
void print(long val);
void print(float val);
void print(double val);
This saves you from having to come up with a unique name for each function. At compile time, the compiler chooses amongst these functions based on the type of the argument.
 
  • Like
Likes yungman
  • #225
Mark44 said:
I put in a quote end tag where I should have put in a code end tag. I've fixed things in my post and in what you quoted.
In C++, but not C, you can have multiple functions with the same name, but with different sets of arguments. For example, you could have multiple functions named print, with each designed to print a different type of value.
C++:
void print(int val);
void print(long val);
void print(float val);
void print(double val);
This saves you from having to come up with a unique name for each function. At compile time, the compiler chooses amongst these functions based on the type of the argument.
I did not know that! o_O :))

So overload is how many times you can use the same name with different sets of arguments?
 
  • #226
yungman said:
So overload is how many times you can use the same name with different sets of arguments?
Sort of. It's not how many times. In my example the print function had four overloads.
 
  • Like
Likes yungman
  • #227
I have an issue with this program that I can't fix. I copied the code from the book, everything looks right. I got an warning error and it won't run. I only typed in "This is " into St1 and "A test" into St2, way under the size. At the beginning, I chose to run it anyway and it print out the input but not after strncat. Now, it won't even do anything.

C++:
//Function for strings
#include <iostream>
#include<cstring>
using namespace std;

int main()
{
    int maxCh;
    char St1[50], St2[50];
    cout << " Enter a sentence 1: ";
    cin.getline(St1, 50); cout << "\n\n";
    cout << " You entered " << St1 << "\n\n";

    cout << " Enter a sentence 2: ";
        cin.getline(St2, 50); cout << "\n\n";
    cout << " You entered " << St2 << "\n\n";
    maxCh = sizeof(St1) - (strlen(St1) + 1);
    strncat(St1, St2, maxCh);
    cout << " After strncat, St1 = " << St1 << "\n\n";
    return 0;
}
Compile error Listing 7.2.jpg

Thanks
 
Last edited:
  • #228
Here's what's wrong with your code.
Microsoft deprecated several of the string manipulation functions several versions of VS ago. Among them are strcpy(), strcat(), and others, including strncat(). The reason for this is that they are unsafe, and using them could lead to buffer overruns, which hackers could use to hack into a computer that is running a program using these functions. Back in about 2004, Microsoft spent a lot of money on training for everyone , and I mean everyone, in the Windows division (about 7500) people to take training to raise awareness on the problems with security.

The error you got is because of strncat(). Use the safe version, strncat_s. Here are the docs for it: https://docs.microsoft.com/en-us/cp...csncat-s-l-mbsncat-s-mbsncat-s-l?view=vs-2019
Note that this is a Microsoft-specific string function.
It's the first one listed.

In your program, this will work - strncat_s(St1, 50, St2, 25);
Here, St1 is the destination - it has to have enough space to hold both strings.
50 is the size of the destination buffer.
St2 is the source string.
25 is the number of characters to concatenate onto the source.

Normally it's bad practice to have "magic numbers" like 50 and 25 above. It's much better to use constants or variables that get computed, but I put something together in a hurry.

C++:
//Function for strings
#include <iostream>
#include<cstring>
using namespace std;

int main()
{
    int maxCh;
    char St1[50], St2[50];
    cout << " Enter a sentence 1: ";
    cin.getline(St1, 50); cout << "\n\n";
    cout << " You entered " << St1 << "\n\n";

    cout << " Enter a sentence 2: ";
        cin.getline(St2, 50); cout << "\n\n";
    cout << " You entered " << St2 << "\n\n";
    maxCh = sizeof(St1) - (strlen(St1) + 1);                        
    strncat(St1, St2, maxCh);                                               
    cout << " After strncat, St1 = " << St1 << "\n\n";
    return 0;
}
 
Last edited:
  • Like
Likes sysprog and yungman
  • #229
Compile error Listing 7.2.jpg

Mark44 said:
Here's what's wrong with your code.
1. Your definition of maxCh is wrong. As you have it, maxCh will be set to -1.
Microsoft deprecated several of the string manipulation functions several versions of VS ago. Among them are strcpy(), strcat(), and others, including strncat(). The reason for this is that they are unsafe, and using them could lead to buffer overruns, which hackers could use to hack into a computer that is running a program using these functions. Back in about 2004, Microsoft spent a lot of money on training for everyone , and I mean everyone, in the Windows division (about 7500) people to take training to raise awareness on the problems with security.

The error you got is because of strncat(). Use the safe version, strncat_s. Here are the docs for it: https://docs.microsoft.com/en-us/cp...csncat-s-l-mbsncat-s-mbsncat-s-l?view=vs-2019
Note that this is a Microsoft-specific string function.
It's the first one listed.

In your program, this will work - strncat_s(St1, 50, St2, 25);
Here, St1 is the destination - it has to have enough space to hold both strings.
50 is the size of the destination buffer.
St2 is the source string.
25 is the number of characters to concatenate onto the source.

Normally it's bad practice to have "magic numbers" like 50 and 25 above. It's much better to use constants or variables that get computed, but I put something together in a hurry.

C++:
//Function for strings
#include <iostream>
#include<cstring>
using namespace std;

int main()
{
    int maxCh;
    char St1[50], St2[50];
    cout << " Enter a sentence 1: ";
    cin.getline(St1, 50); cout << "\n\n";
    cout << " You entered " << St1 << "\n\n";

    cout << " Enter a sentence 2: ";
        cin.getline(St2, 50); cout << "\n\n";
    cout << " You entered " << St2 << "\n\n";
    maxCh = sizeof(St1) - (strlen(St1) + 1);                        
    strncat(St1, St2, maxCh);                                               
    cout << " After strncat, St1 = " << St1 << "\n\n";
    return 0;
}
Thanks for the reply. I have to read the rest in detail.

I don't understand your first point that maxCh will be set to -1.

in maxCh = sizeof(St1) - (strlen(St1) + 1); sizeof(St1) = 50. strlen(St1) depends on what I enter into St1. Like I said in my post, I enter "This is " for St1. This is 8 characters total ( including space). With the '\0', it's 9 character. maxCh should equal to 50 - 8 -1 = 41. I input to St2 = "a test". Total of St2 is 6characters. There should be plenty of room and not a chance to overrun.

thanks
 
  • #230
yungman said:
I don't understand your first point that maxCh will be set to -1.
My mistake -- I read your code too quickly, thinking it said sizeof(St1) - (sizeof(St2 + 1)).
It's gettin' late for me...
 
  • #231
Note that std::string automatically allocates enough new memory to accommodate the result of any string operation. There's no need to deal with buffer-overrun issues.

(Note getline() for std::string is different than for char arrays.)

Code:
#include <iostream>
#include <string>

using namespace std;

int main ()
{
    string St1, St2;
    cout << " Enter a sentence 1: ";
    getline (cin, St1); cout << "\n\n";
    cout << " You entered " << St1 << "\n\n";
    cout << " Enter a sentence 2: ";
    getline (cin, St2); cout << "\n\n";
    cout << " You entered " << St2 << "\n\n";
    St1 = St1 + St2;  // St1 automatically expands as needed
//  Or you can use St1 += St2;
    cout << " After concatenation, St1 = " << St1 << "\n\n";
    return 0;
}
 
Last edited:
  • Like
Likes yungman
  • #232
jtbell said:
Note that std::string automatically allocates enough new memory to accommodate the result of any string operation. There's no need to deal with buffer-overrun issues.

(Note getline() for std::string is different than for char arrays.)

Code:
#include <iostream>
#include <string>

using namespace std;

int main ()
{
    string St1, St2;
    cout << " Enter a sentence 1: ";
    getline (cin, St1); cout << "\n\n";
    cout << " You entered " << St1 << "\n\n";
    cout << " Enter a sentence 2: ";
    getline (cin, St2); cout << "\n\n";
    cout << " You entered " << St2 << "\n\n";
    St1 = St1 + St2;  // St1 automatically expands as needed
//  Or you can use St1 += St2;
    cout << " After concatenation, St1 = " << St1 << "\n\n";
    return 0;
}
Thanks, I am reading strings right now, I just want to follow the book, learn as much as I can of each topic.
 
  • #233
Mark44 said:
My mistake -- I read your code too quickly, thinking it said sizeof(St1) - (sizeof(St2 + 1)).
It's gettin' late for me...
I made that mistake when I first read this in the book also.

I read your link on strncat_s, it is difficult to understand as they use stuffs I don't know. I actually followed your explanation and it works. This is the program after changing to strncat_s.
C++:
//Function for strings
#include <iostream>
#include<cstring>
using namespace std;

int main()
{
    int maxCh;
    const int size1 = 50;
    char St1[size1+21], St2[size1];
    cout << " Enter a sentence 1: ";
    cin.getline(St1, size1); cout << "\n\n";
    cout << " You entered " << St1 << "\n\n";

    cout << " Enter a sentence 2: ";
        cin.getline(St2, size1); cout << "\n\n";
    cout << " You entered " << St2 << "\n\n";
    maxCh = sizeof(St1) - (strlen(St1) + 1);
    strncat_s(St1, size1, St2, 20);
    cout << " After strncat, St1 = " << St1 << "\n\n";
    strcpy_s(St1, 5, St2);
    cout << " St1 after copying from St2 to St1 when set max copy 5 char = " << St1 << "\n\n";
    return 0;
}

I changed using const int size1 instead of a number and I change the size of St1 = (size1+21) in line 10 and use strncat_s(St1, size1, St2, 20);

I even experimented with strncpy_s. This one can still gives warning when I set the middle integer to 5 and St2 is larger. In my case St2="a test"(6 char). It will copy the whole "a test" over, but gave me a warning:

Compile error Listing 7.2.jpg


Like I said, I searched on line, There are very few and I couldn't understand them. So I just kind of guessing how strncpy_s works.

These must not be that popular as Jtbell said, use string instead to avoid all these problems.

thanks
 
  • #234
I want to confirm is C=String actually a string of characters stored in character array. That it is NOT a String. That C-String is subject to a lot of limitation like the size and all seen in strcat, strcpy. Even strncat_s and strncpy_s is NOT very convenient. Why are we still using C-String given all these limitation. Just use String Class.

I have been trying to search on line, what is size_t? I read on line and I still don't understand, they said it's like sizeof but with unlimited size. What is that? I looked at the index of two books and couldn't find it.
It is found in size_t found = St1.find(St2); where I want to find string St2 inside St1. I want to do the same thing like strstr in C-String.

Also what is errno_t? Couldn't find it in both books. A lot of this and size_t pop up around the search of strcat, strcpy. like the following code, I have no idea what these mean. Thereby not very fruitful searching on web.
:
errno_t _strncat_s_l( char *strDest, size_t numberOfElements, const char *strSource, size_t count, _locale_t locale );

Thanks
 
Last edited:
  • #235
yungman said:
I want to confirm is C=String actually a string of characters stored in character array.
I wrote this in post #222:
Mark44 said:
A C-string is a null terminated array of characters.
yungman said:
That it is NOT a String. That C-String is subject to a lot of limitation like the size and all seen in strcat, strcpy. Even strncat_s and strncpy_s is NOT very convenient. Why are we still using C-String given all these limitation. Just use String Class.
A C string is different from a C++ Standard Template Library string. This is one of the more confusing aspects in C++, as it combines how character strings are dealt with in C together with a completely new and different concept in C++.
yungman said:
I have been trying to search on line, what is size_t? I read on line and I still don't understand, they said it's like sizeof but with unlimited size.
No, they didn't say it's like sizeof -- they said it's the type returned by the sizeof operator. See http://www.cplusplus.com/reference/cstring/size_t/.
yungman said:
Also what is errno_t?
It's a type that is Microsoft-specific, that represents the type of return value. As far as I know, it's just an int. The important thing is to recognize from the return value whether the function call succeeded or not.
 
  • Like
Likes yungman and pbuk
  • #236
This thread has grown very long, so I'm closing it.
@yungman, when you have more questions about a specific topic, please start a new thread, but don't make the thread a grab-bag of questions about different topics.

I'm sure that a lot of your questions have been answered in this thread, but a thread with 236 posts is of very limited usefulness to someone wanting to learn C++.
 
  • Like
Likes phinds

Similar threads

Replies
7
Views
2K
Replies
6
Views
2K
Replies
1
Views
1K
Replies
5
Views
2K
Replies
75
Views
5K
Replies
17
Views
2K
Replies
9
Views
2K
Back
Top