0

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.

5
  • 2
    Here, name, lastname are not given initial values because they are given values with cin.getline(). fullname could be initialised in this situation but for whatever reason it is not. In cases such as this however, I think it is preferable to use std::string and std::getline rather than plain char arrays. Commented Apr 22, 2014 at 0:25
  • 2
    Looks more like a C tutorial with a few sprinklings of C++. Commented Apr 22, 2014 at 0:26
  • 2
    These are not strings ;-). They are character arrays. Commented Apr 22, 2014 at 0:29
  • If you use std::string, it initializes the variable so there are no worries. Commented Apr 22, 2014 at 0:29
  • I got it. Also, I figure the tutorial I read on cprogramming.com might be a little outdated. Many thanks, everyone! Commented Apr 22, 2014 at 2:33

5 Answers 5

2

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.

Sign up to request clarification or add additional context in comments.

Comments

1

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.

6 Comments

I see. That's what I'm looking for; Cuz I did try to commentize the "fullname[0] = '\0';" and it still ran smoothly. But from other people's replies, I figure the tuturial I read on cprogramming.com might be a little outdated. Many thanks, everyone!
IMHO, I think it is always wise to initialize any variable, regardless of whether you will be reading/writing from/to it. For eg, in your case, char a[20] = {0};.
That is for better safe than sorry?
@brokenfoot I'd say that is a fallacy, if the immediate action after declaring it is initializing it with some library method, what purpose does it serve to do initialize it twice? There are alot of C libraries take the value it wants to initialize as a pointer parameter, and return an error indicator, so you cannot do it as an assignment on declaration. In the case where you apply this to C++ libraries, values have default initializers, and any good design will have them initialized in a sane manner unless there is a good reason not to.
@CasperVonB: Yes, I agree, that depends on how you are using your variables in the code. But I was talking about more of a general scenario. As most of the errors beginners deal with are using variables containing garbage values where they assume it to contain some valid data.
|
0

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 ^^.

4 Comments

This fills the buffer with the digit 0, (as in, the digit before 1), not the null character, which is '\0'.
Also, sizeof(char) is guaranteed to be 1. Lastly, char a[50] = {}; (or char a[50] = {0}; for regular C) will also work for zeroing out the entire array.
@dreamlax, as you said, on regular C compiler, if u want to try something weird you can have some weird problems, that is why i always do sizeof(char)
sizeof(char) is guaranteed to be 1 for both C and C++. If sizeof(char) is anything but 1, you are not dealing with a standards-compliant C or C++ compiler.
0

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.

Comments

0

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.

2 Comments

When I was reading that, I also wondered the arithmetic here, and I figured out that's 49 (50(firstname) - 1(end of string)) + 1 (space) + 49 (50-1) + 1 (end of string) = 100.
@NickChen Woops! That is true, when i changed it to 101 it slipped my mind that the 0 terminator from first_name and last_name would be dropped and the strings are only containing 49 characters at most. So as you said a buffer of 100 would obviously be enough to hold 2 * 49 + 2 (whitespace and terminator).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.