Why does it work? Using cin to read into char array is less than given input

I am reading C ++ Primer Plus (6th edition), and I came across some code example in chapter 4 in which I have a question:

Listing 4.2 strings.cpp

// strings.cpp -- storing strings in an array #include <iostream> #include <cstring> // for the strlen() function int main() { using namespace std; const int Size = 15; char name1[Size]; // empty array char name2[Size] = "C++owboy"; // initialized array // NOTE: some implementations may require the static keyword // to initialize the array name2 cout << "Howdy! I'm " << name2; cout << "! What your name?\n"; cin >> name1; cout << "Well, " << name1 << ", your name has "; cout << strlen(name1) << " letters and is stored\n"; cout << "in an array of " << sizeof(name1) << " bytes.\n"; cout << "Your initial is " << name1[0] << ".\n"; name2[3] = '\0'; // set to null character cout << "Here are the first 3 characters of my name: "; cout << name2 << endl; return 0; } 

The code itself is not confusing, but I ran it, and I am confused by a specific scenario.

name1 is initialized as an array of characters with a length of 15 elements. Do I think it should contain a string of 14 characters? The end of char must be reserved for the string terminator, right?

If I enter my name as HowCanIPossiblyFitThisEntireStringIn? I get the following output:

Howdy! I am C ++ owboy! What is your name?

HowCanIPossiblyFitThisEntireStringIn?

Well, HowCanIPossiblyFitThisEntireStringIn ?, your name has 37 letters and is stored

in an array of 15 bytes.

H. first

Here are the first 3 characters of my name: C ++

How is the whole name that I entered written down? If I go through the code after reading cin in name1, Visual Studio will tell me that it contains elements 0-14, the last of which is char 'y' ("HowCanIPossibly ...). I would suggest that any extra input the data was truncated and lost, but this is obviously not the case, since the next cout successfully writes the entire name to the console.

For curiosity, can someone enlighten me about what is happening here? For recording I use Visual Studio 2012 Express.

+4
source share
2 answers

You write the boundaries of the array. The C ++ standard does not say that this should be a mistake; he says that this behavior is undefined. This means that everything can happen, including the seemingly correct operation. Simply put, your code does not have well-defined behavior, so you should not trust it to work.

We can imagine why this probably works. The first 15 characters will fit well into the array:

 |H|o|w|C|a|n|I|P|o|s|s|i|b|l|y|F|i|t|T|h|i|s|E|n|t|i|r|e|S|t|r|i|n|g|I|n|?|... ^ ^ | These characters fit | in the array 

The remaining characters are written to the following memory locations. Now remember that the null character that is used to end C-style strings is defined as having a representation of 0 bits. Now, if the location next to the location containing ? has all 0 bits in it, the string will appear to be zero.

But the fact is that it is undefined. It just works. Unfortunately, this is the worst type of error, because it can work for a long time, until one day you start receiving calls from your very, very angry client.

+7
source

You can use istream::get with a buffer and buffer size:

 cin.get(name1, Size); 

As others have noted, it is much easier to use std::string :

 std::string name1; cin >> name; 
+2
source

All Articles