[c] Assigning strings to arrays of characters

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?

This question is related to c

The answer is


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 assignment 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 be pointing 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.


There is no such thing as a "string" in C. In C, strings are one-dimensional array of char, terminated by a null character \0. 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 = strncpy(s, "hello", STRMAX);

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++


What I would use is

char *s = "abcd";

I know that this has already been answered, but I wanted to share an answer that I gave to someone who asked a very similar question on a C/C++ Facebook group.


Arrays don't have assignment operator functions*. This means that you cannot simply assign a char array to a string literal. Why? Because the array itself doesn't have any assignment operator. (*It's a const pointer which can't be changed.)

arrays are simply an area of contiguous allocated memory and the name of the array is actually a pointer to the first element of the array. (Quote from https://www.quora.com/Can-we-copy-an-array-using-an-assignment-operator)

To copy a string literal (such as "Hello world" or "abcd") to your char array, you must manually copy all char elements of the string literal onto the array.

char s[100]; This will initialize an empty array of length 100.

Now to copy your string literal onto this array, use strcpy

strcpy(s, "abcd"); This will copy the contents from the string literal "abcd" and copy it to the s[100] array.

Here's a great example of what it's doing:

int i = 0; //start at 0
do {
    s[i] = ("Hello World")[i]; //assign s[i] to the string literal index i
} while(s[i++]); //continue the loop until the last char is null

You should obviously use strcpy instead of this custom string literal copier, but it's a good example that explains how strcpy fundamentally works.

Hope this helps!


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


You can use this:

yylval.sval=strdup("VHDL + Volcal trance...");

Where yylval is char*. strdup from does the job.


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.


Note that you can still do:

s[0] = 'h';
s[1] = 'e';
s[2] = 'l';
s[3] = 'l';
s[4] = 'o';
s[5] = '\0';