tags:

views:

131

answers:

5

Why is the following code illegal?

typedef struct{
   char a[6];
} point;

int main()
{
   point p;
   p.a = "onetwo";
}

Does it have anything to do with the size of the literal? or is it just illegal to assign a string literal to a char array after it's declared?

+5  A: 

It doesn't have anything to do with the size. You cannot assign a string literal to a char array after its been created - you can use it only at the time of definition.

When you do

char a[] = "something";

it creates an array of enough size (including the terminating null) and copies the string to the array. It is not a good practice to specify the array size when you initialize it with a string literal - you might not account for the null character.

When you do

char a[10];
a = "something";

you're trying to assign to the address of the array, which is illegal.

EDIT: as mentioned in other answers, you can do a strcpy/strncpy, but make sure that the array is initialized with the required length.

strcpy(p.a, "12345");//give space for the \0
Amarghosh
+4  A: 

You can never assign to arrays after they've been created; this is equally illegal:

int foo[4];
int bar[4];
foo = bar;

You need to use pointers, or assign to an index of the array; this is legal:

p.a[0] = 'o';

If you want to leave it an array in the struct, you can use a function like strcpy:

strncpy(p.a, "onetwo", 6);

(note that the char array needs to be big enough to hold the nul-terminator too, so you probably want to make it char a[7] and change the last argument to strncpy to 7)

Michael Mrozek
I guess I should be flattered that every answer edited in my `strcpy` solution
Michael Mrozek
@Michael Mrozek: Here, have a +1. I'd +2 if I could, but I find it a bit odd that nobody has yet noticed that this is a `struct` containing an array, not just a plain array.
dreamlax
Of course, "strncpy" comes with its own problems, unlike most of the other "n" functions.
David Thornley
+8  A: 

Arrays are non modifiable lvalues. So you cannot assign to them. Left side of assignment operator must be an modifiable lvalue.

However you can initialize an array when it is defined.

For example :

 char a[] = "Hello World" ;// this is legal
 char a[]={'H','e','l','l','o',' ','W','o','r','l','d','\0'};//this is also legal

 //but

 char a[20];
 a = "Hello World" ;// is illegal 

However you can use strncpy(a, "Hello World",20);

Prasoon Saurav
It would be clearer if you used the correct term 'initialize' instead of 'assign' when an array is 'defined' (rather than 'declared').
Jonathan Leffler
@Jonathan : Yes you are pedantically correct. Fixed! :)
Prasoon Saurav
A: 

Note that in order to store the string "onetwo" in your array, it has to be of length [7] and not as written in the question. The extra character is for storing the '\0' terminator.

ysap
+2  A: 

As other answers have already pointed out, you can only initialise a character array with a string literal, you cannot assign a string literal to a character array. However, structs (even those that contain character arrays) are another kettle of fish.

I would not recommend doing this in an actual program, but this demonstrates that although arrays types cannot be assigned to, structs containing array types can be.

typedef struct
{
    char value[100];
} string;

int main()
{
    string a = {"hello"};
    a = (string){"another string!"}; // overwrite value with a new string
    puts(a.value);

    string b = {"a NEW string"};
    b = a; // override with the value of another "string" struct
    puts(b.value); // prints "another string!" again
}

So, in your original example, the following code should compile fine:

typedef struct{
    char a[6];
} point;

int main()
{
   point p;

   // note that only 5 characters + 1 for '\0' will fit in a char[6] array.
   p = (point){"onetw"};
}
dreamlax
+1 for the `struct` examples, but note that these compound literals are a C99 addition. (Same goes for the '//' style comment.)
schot