Reputation: 3
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.
Upvotes: 0
Views: 898
Reputation: 2301
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.
Upvotes: 0
Reputation: 145239
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
.
Upvotes: 0
Reputation: 1768
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 ^^.
Upvotes: 0
Reputation: 14688
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.
Upvotes: 2
Reputation: 11609
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.
Upvotes: 1