简体   繁体   中英

Why and when do we have to initialize a string before using in C++?

I was reading some C++ tutorial and find that sometimes a string is initialized ('initialized' may not be the proper term), sometimes not.

Why and when?

The code I was reading is:

char name[50];
char lastname[50];
char fullname[100];
...
cin.getline ( name, 50 );
...
cin.getline ( lastname, 50 );
fullname[0] = '\0';            // strcat searches for '\0' to cat after
strcat ( fullname, name );     // Copy name into full name
strcat ( fullname, " " );      // We want to separate the names by a space
strcat ( fullname, lastname ); // Copy lastname onto the end of fullname

Someone please kindly explain.

In C++, there are character arrays like char name[50] , and there are string classes, like std::string .

The character arrays are initialized according to the same rules are they are in C -- that is, if they are stack variables they are not initialized and if the are static / globals they are initialized to zero at load time -- there are however exceptions based on system specifics, so best is to assume that they are never initialized.

string classes (like std::string) are initialized as part of the constructor phase of the object -- so they are always initialized.

In your specific code, you are using character arrays of a fixed length. They are usually null terminated, but they may not always be -- specifically cin.getline ( name, 50 ); will read full 50 characters, and it will leave the data null terminated if there are 49 characters or less in the input, but as there is no space for more than 50 characters it will not null terminate if there are 50 characters or more -- this has implications on your strcat , as strcat assumes the data is null terminated -- you must use strncat instead to make the code safe.

Its the same like any other datatype. By default, local variables contain garbage values. So, you initialize it if you will be reading its value. But if you know that you will be writing to the variable, than you can skip the initialization part.

For eg:

char a[20]; //local variable

contains garbage, so you need to write some meaningful data to it before reading it. But if you are just writing to it, then you can skip the initialization.

What you have there is an allocation on the stack. The compiler don't guarantees that the memory allocated is empty, so you can have junk on it, that is why you need to fill with 0 to clear the junk.

you can do that with

memset(pointer, '0', size);

example

char a[50]

memset(a, NULL, sizeof(char)*50);

When depends on what you are doing, if you want to write some data inside it and read, the \\0 will probably save you as it is the deadline, if you want to read all the data, char a[50] the 50 bytes ignoring the \\0, so you need to clear the data. The way to go is to clear the data inside ^^.

first_name , last_name do not get initialized immediatly because the next two lines initializet them immediatly after and full_name gets a 0 terminator so it will represent an empty string which can be concatenated upon with std::strcat.

char first_name[50];
char last_name[50];

// There is no need to initialize first_name and last_name,
// they will contain garbage as with any uninitialized values but they get
// overwritten here when reading from stdin anyways.
cin.getline ( first_name, 50 );
cin.getline ( last_name, 50 );

char full_name[100];
// Again full_name contains garbage, so it gets a 0 terminator here in order
// to have it represent an empty string.
full_name[0] = '\0';

// full_name had to be an empty string in order to concatenate
// onto it using strcat
strcat ( full_name, first_name );
strcat ( full_name, " " );
strcat ( full_name, last_name );

That being said, these are C style strings and you would most likely prefer to just use std::string instead.

cin.getline does not use or inspect the original value of the buffer you pass in, so for that function the buffer doesn't need to be initialized.

strcat , in contrast, checks the existing buffer contents to determine where it should tack on the specified string characters. Therefore, with strcat the buffer must be initialized, and not just arbitrarily, but with some zero-byte that marks the logical end-of-string position.


As others have remarked, the code shown is very unsafe. It's unsafe because (not yet remarked on as I write this) a maintenance programmer may not realize that full_name has exactly the required buffer size to hold a maximum length first name plus a space plus a maximum size last name. This should at the least have been explained in a comment.

But better than a comment, safer length-checking functions should have been used.

And except for learning, even better is to use a string class such as std::string .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM