tags:

views:

203

answers:

6

I am a little surprised by the following.

Example 1:

char s[100] = "abcd"; // declare and initialize - WORKS

Example 2:

char s[100]; // declare
s = "hello"; // initalize - DOESN'T WORK ('lvalue required' error)

I'm wondering why the second approach doesn't work. It seems natural that it should (it works with other data types)? Could someone explain me the logic behind this?

+6  A: 

Initialization and assignment are two distinct operations that happen to use the same operator ("=") here.

Sparr
+4  A: 

There is no such thing as a "string" in C. Strings are arrays of char, terminated by NULL by convention. Since you can't assign arrays in C, you can't assign strings either. The literal "hello" is syntactic sugar for const char x[] = {'h','e','l','l','o','\0'};

The correct way would be:

char s[100];
strncpy(s, "hello", 100);

or better yet:

#define STRMAX 100
char    s[STRMAX];
size_t  len;
len = strlcpy(s, "hello", STRMAX);
dwc
-1 for #defining STRMAX and not using char s[STRMAX]!!
Orion Edwards
+1 for getting down-voted for silly reasons
Sean Bright
Sean: thanks! That made me laugh
dwc
+1 for fixing the answer :-)
Orion Edwards
+7  A: 

When initializing an array, C allows you to fill it with values. so

char s[100] = "abcd";

is basically the same as

int s[3] = { 1, 2, 3 };

but it doesn't allow you to do the assignmend since s is an array and not a free pointer. the meaning of

s = "abcd"

is to assign the pointer value of "abcd" to 's' but you can't change s since then nothing will point to the array.
This can and does work if s is a char* - a pointer that can point to anything.

if you want to copy the string simple use strcpy

shoosh
Good answer, except you should never use plain strcpy any longer. Use strncpy or strlcpy.
dwc
Also, s should be const char*, not char*.
aib
A: 
1    char s[100];
2    s = "hello";

In the example you provided, s is actually initialized at line 1, not line 2. Even though you didn't assign it a value explicitly at this point, the compiler did. At line 2, you're performing an assignment operation, and you cannot assign one array of characters to another array of characters like this. You'll have to use strcpy() or some kind of loop to assign each element of the array.

Matt Davis
A: 

To expand on Sparr's answer

Initialization and assignment are two distinct operations that happen to use the same operator ("=") here.

Think of it like this:

Imagine that there are 2 functions, called InitializeObject, and AssignObject. When the compiler sees thing = value, it looks at the context and calls one InitializeObject if you're making a new thing. If you're not, it instead calls AssignObject.

Normally this is fine as InitializeObject and AssignObject usually behave the same way. Except when dealing with char arrays (and a few other edge cases) in which case they behave differently. Why do this? Well that's a whole other post involving the stack vs the heap and so on and so forth.

PS: As an aside, thinking of it in this way will also help you understand copy constructors and other such things if you ever venture into C++

Orion Edwards
A: 

Note that you can still do:

s[0] = 'h';
s[1] = 'e';
s[2] = 'l';
s[3] = 'l';
s[4] = 'o';
s[5] = '\0';
aib
It's much nicer and easier to use strncpy(), even though I'm pretty sure strncpy() does exactly this internally.
Chris Lutz
Of course. But this is as close as it gets to 's = "hello";' In fact, this should have been implemented in C, seeing as how you can assign structs.
aib
I mean, memberwise copy by assignment in structs but not in arrays doesn't make sense.
aib