1

My book says that if I want to read a string with a maximum length of 40 characters, I have to declare a variable with a length of 41, but it doesn't say why.

char name[41];
cin >> name;
cout << name << endl;

I know this is a newbie question and indeed I'm a C++ newbie.

I hope you can help me. Thanks.

EDIT:

Thanks for the answers, I didn't expect so much great information in such short time.

  1. Who is in charge of inserting the NULL terminator at the end of the char array?

  2. What happens with the "\n" after I press Enter?

Thanks again.

5
  • Because you must have a null character at the end of your string. Commented Mar 28, 2014 at 17:10
  • @Aliou, post that as the answer. Don't think there's much more to say. Commented Mar 28, 2014 at 17:12
  • std::string theoretically has no maximum. Don't use c-style strings in c++ Commented Mar 28, 2014 at 17:14
  • @MarkRenton: The answers are already provided, but I think the most important advice is missing: get a better (and perhaps newer) book. If it exposes you to char* before explaining std::string, then chances are it's from the 90s, when people often used, teached and learned "C with Classes" instead of C++ :) Commented Mar 28, 2014 at 17:55
  • string literals in C and C++ are always 0-terminated. You can get aroud it this way: char notermination[4]="Damn";, but that is seldom useful for anything. BTW: Ask a new question if you have need of more information. But preferably search this site with appropriate keywords first. Best of course would be figuring it out from the standard itself. Commented Mar 31, 2014 at 14:36

4 Answers 4

5

Use a std::string to read from cin. Then you do not need to know in advance how big your buffer needs to be.

std::string input;
cin >> input;
cout << intput;

If you need a C-style array you can do:

const char* cstyle = input.c_str();

If you use a C-style string, the last character is always the null terminator '\0' to indicate the end of the string. This is important to know where your sequence of characters ends.

Some example:

char* text = "hello"; // the compiler puts an extra '\0' at the end
std::string str("hello"); // does not have a null terminator! (before C++11)
str.c_str(); // this returns "hello\0" with a null terminator
Sign up to request clarification or add additional context in comments.

5 Comments

So, std::string is more convenient, but char[] is more performant. Before you decide on chucking abstractions for that reason, measure and provide an ironclad case.
std::string does store a terminating 0, always, just so 'c_str()` can be constant.
@Deduplicator: This is not true before C++11. See here: stackoverflow.com/questions/11752705/…
Thanks, but anyway: AFAIK no implementation ever used that leeway, and I don't want to think about what all would have broken if any did.
Well it is/was quite important to not assume that const char* p = str.begin(); gives a sequence with a null-terminator. But if you use c_str() you are safe.
1

There are two ways of declaring a string in C++:

char name[41];

or

string name;

One main difference between these is that there is always a \0 character at the end of the character array to signify the end of it, so there is an extra cell required. Using string would be more convenient as you don't have to care about the length of the string. (And you can also use many build-in functions from the string library)

Check this out: Difference between string and char[] types in C++

2 Comments

Actually, even though C++ basicstring<> (string, wstring, ...) uses counted strings, they are also guaranteed to be null-terminated.
std::basic_string does not use reference counting in MSVC, and even in GCC, the behaviour will perhaps change sooner or later due to C++11 practically forbidding reference-counted strings.
0

The answer is that strings stored in character arrays, raw strings, are terminated with the null character ('\0'). This control character signals the end of the string. This terminator is useful because the length of the string doesn't need to be stored explicitly. It's also useful because strings of any length that can fit in the array are allowed. In this situation, it's useful to have a marker for the end of the string. This question should prove useful in understanding the subject further.

Comments

0

A C-style string is an array of chars, the end of which is marked by a NUL terminator (i.e. a char having all its bits set to 0).

So, the string "Hi" looks like this in memory:

+-----+-----+-----+
|  H  |  i  | NUL |
+-----+-----+-----+

As you can note, a string of 2 characters ("Hi") actually requires 3 (i.e. 2+1) characters, including the NUL terminator.

This is why a C-style string of 40 characters requires an array of 41 (i.e. 40+1) characters, because it must include room for the NUL terminator.


As a side note, I'd suggest using a robust and convenient string class in C++ (e.g. std::string), instead of raw C-style arrays of characters with a NUL terminator.
If you use a string class, you'll make your code simpler, and you'll help yourself avoiding several potential security problems (e.g. buffer overruns) that are more likely to happen with raw C-style strings.

This would work just fine for string input in C++:

#include <iostream> // For std::cin/std::cout
#include <string>   // For std::string

....

std::string name;
std::cin >> name;                // Input
std::cout << name << std::endl;  // Output

3 Comments

Thanks for the answers, I didn't expect so much great information in such short time. Just 2 questions came up in my mind: Who is in charge of inserting the NULL terminator at the end of the string? What happens with the "\n" after I press Enter? Thanks again.
@MarkRenton: You're welcome. The NUL terminator is set by C functions like strcpy() in the destination strings; the NUL terminator is managed by the std::string class if you use that; the NUL terminator is automatically inserted by the C/C++ compiler if you define the string as in char s[] = "hello";. When you read the string using cin as in string s; cin >> s;, the '\n' is discarded (it's not stored in the read string).
@MarkRenton: BTW: If you find the answers in this thread helpful, you may want to upvote all of them as a good StackOverflow citizen, and mark the best reply as answer.

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.