1

I got confused with string initialization. I believe that the following:

case1:

char s1[100] = { "apple" };

case2:

char s1[100];
s1 = "apple";

case1 compiles ok, however, case2 gets error. Compiler says I am trying to assign char[5] to char[100]... Could you clarify the difference between two cases?

2 Answers 2

4

Explanation of current code

case 1 is a legal way to initialise s1, with 'a' going into [0], 'p' into [1] and [2], 'l' into [3], 'e' into [4] and the rest set to 0 (ASCII NUL - see http://en.wikipedia.org/wiki/ASCII).

case 2 attempts to assign one array to another (of a different size as per the message), which isn't legal in C++. You should use strcpy(s1, "apple") to do this, though it differs slightly in behaviour: it will only set s1[5] to 0/NUL, with [6] onwards unaffected (if s1 is on the stack or heap they'll be uninitialised and reading from them will be undefined behaviour). Most things you'd want to do with s1 won't benefit from initialisation of [6] onwards....

An intuitive alternative: `std::string`

Perhaps the best approach is to switch to std::string, which works more intuitively (you'll have to #include <string> atop your program). The syntax for case 1 will be slightly different though: either std::string s1 = "apple";, or - if you have a C++11 compiler - std::string s1 { "apple" };.

Writable buffers versus pointers to string literals

Note too that in your question, char s1[100] creates an array of 100 characters that you can read and write to, and you're then copying from a read-only ("const") string literal into that writable buffer. If you just want to keep track of the text (e.g. that it's "apple" as opposed to say "orange" which might be copied into s1 later) without needing to modify the text further, you can use a const char* to store the address of the string literal:

const char* p_s1 = "apple";
if (f()) p_s1 = "orange";
std::cout << "go eat an " << p_s1 << '\n';

As an example of the const nature of string literals, with the const char* p_s1 above you can't modify the pointed-to string literals as in:

#include <cctype>
...
p_s1[0] = std::toupper(p_s1[0]);   // oops! p_s1[0] inside string literal - mustn't write

Whereas if you'd stuck with char s1[100]; you could do:

s1[0] = std::toupper(s1[0]);       // ok
Sign up to request clarification or add additional context in comments.

5 Comments

Well, "of a different size", direct assignment of same size array isn't valid either.
What about char s1[100] = "apple"; (without braces)? Strangely, the compiler does not complain.
@Peter: that's initialization, not assignment.
I thought an assignment is the same as an initialization, however it's not. Thank you!
@Peter: in general, initialisation is what happens to set the previously uninitialised memory to a valid state for a variable of that type - that might be orchestrated by the compiler using knowledge of the OS executable loader's behaviours in terms of 0ing out certain memory areas, or faulting values in from the executable image that are immediately usable, or it might involve some run-time setting of data or constructor call. The variable's then usable by the program, its destructor is guaranteed to be called if it leaves scope etc.. Assignment modifies such a pre-existing object.
2

The buit-in arrays (so called raw arrays) do not support direct assignment.

Your case 1 is not assignment: it's initialization.

The standard library offers std::array which essentially wraps a raw array in a struct, and thus is assignable.

However, for the apparent purpose of your code an array would be the wrong choice.

Instead use a std::string, which supports both initialization from and assignment of a string literal.


Example (include <string>):

using std::string;
string s1 = "apple";
string s2;

s2 = apple;

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.