views:

234

answers:

7

Hi, I am trying to learn the basics, I would think that declaring a char[] and assigning a string to it would work. thanks

int size = 100;
char str[size];

str = "\x80\xbb\x00\xcd";

gives error "incompatible types in assignment". what's wrong? thanks

+7  A: 

You can use a string literal to initialize an array of char, but you can't assign an array of char (any more than you can assign any other array). OTOH, you can assign a pointer, so the following would be allowed:

char *str;

str = "\x80\xbb\x00\xcd";
Jerry Coffin
hm.thanks for help. this is weird to me, that i can declare str[size], then use something like fgets(3) to write to that memory, or strcpy(str2, str) to write to it, but can't set str = "string here"; why is that?
alfo
I'd use a `const char*` when dealing with string literals.
konforce
@alfo: It's simply that C doesn't allow you to modify an array by assigning the contents of another array to it using `=`. There's not really a deep reason *why* - it's just that the language requires you to use another mechanism (`memcpy()` in general) to do that.
caf
A: 

To assign a String Literal to the str Array you can use a the String copy function strcpy.

Christian Ammer
To be more precise: you copy characters (the string 'content') rather than "assigning" a value.
Robert
Yes, assign is not correct. I wanted to point out the possibility how to set the str Array.
Christian Ammer
+2  A: 

A char-array can be implicitely cast to a char* when used as Rvalue, but not when used as Lvalue - that's why the assignment won't work.

Robert
+4  A: 

This is actually one of the most difficult parts of learning a programming language.... str is an array, that is, a part of memory (size times a char, so size chars) that has been reserved and labeled as str. str[0] is the first character, str[1] the second... str[size-1] is the last one. str itself, without specifiying any character, is a pointer to the memory zone that was created when you did

char str[size]

As Jerry so clearly said, in C you can not initialize arrays that way. You need to copy from one array to other, so you can do something like this

strncpy(str, "\x80\xbb\x00\xcd", size); /* Copy up to size characters */
str[size-1]='\0'; /* Make sure that the string is null terminated for small values of size */

Summarizing: It's very important to make a difference between pointers, memory areas and array.

Good luck - I am pretty sure that in less time than you imagine you will be mastering these concepts :)

Javier
@Javier: no `str` isn't a pointer. Do a `sizeof str` to see the difference. The easiest way to see it that `str` is 'silently' converted into a pointer on the 'right hand side' of expressions, but not on the left of the assignment statement.
Jens Gustedt
Yes, Jens, you are right- I stand corrected. Thanks a lot for pointing it out :)
Javier
Also you're misusing the word *initialize* in the paragraph beginning "As Jerry so clearly said".
R..
My apologies, English is not my primary language.
Javier
A: 

char a[100] = "\x80\xbb\x00\xcd"; OR char a[] = "\x80\xbb\x00\xcd";

dgnorton
A: 

str is the name of an array. The name of an array is the address of the 0th element. Therefore, str is a pointer constant. You cannot change the value of a pointer constant, just like you cannot change a constant (you can't do 6 = 5, for example).

Kizaru
This is not correct at all. `str` is not a pointer.
dreamlax
Yes, str is an array of characters. But the name str itself, when used in that context, is a pointer constant. Maybe the terminology I used is different, but what else would you call str when used in that context, str = "\x80\xbb\x00\xcd";
Kizaru
"The name of an array is the address of the 0th element. Therefore, str is a pointer constant." You appear to have issue with this statement, so I will clarify. I refer to the address of as a pointer constant. For example, suppose you have int x; int *y ; y =
Kizaru
John Bode
Also, what you call pointer constants are more commonly known as rvalues (i.e. the value of an expression).
dreamlax
+1  A: 

You cannot assign array contents using the =operator. That's just a fact of the C language design. You can initialize an array in the declaration, such as

char str[size] = "\x80\xbb\x00\xcd";

but that's a different operation from an assignment. And note that in this case, and extra '\0' will be added to the end of the string.

The "incompatible types" warning comes from how array expressions are treated by the language. First of all, string literals are stored as arrays of char with static extent (meaning they exist over the lifetime of the program). So the type of the string literal "\x80\xbb\x00\xcd" is "4 5-element array of char". However, in most circumstances, an expression of array type will implicitly be converted ("decay") from type "N-element array of T" to "pointer to T", and the value of the expression will be the address of the first element in the array. So, when you wrote the statement

str = "\x80\xbb\x00\xcd";

the type of the literal was implicitly converted from "4 5-element array of char" to "pointer to char", but the target of the assignment is type "100-element array of char", and the types are not compatible (above and beyond the fact that an array expression cannot be the target of the = operator).

To copy the contents of one array to another you would have to use a library function like memcpy, memmove, strcpy, etc. Also, for strcpy to function properly, the source string must be 0-terminated.

Edit per R's comment below, I've struck out the more dumbass sections of my answer.

John Bode
The string literal `"\x80\xbb\x00\xcd"` already contains a terminating 0, so it's misleading to talk about the final 0 being "added" when using it as an initializer. Further, a partially-initialized object in C always has the remainder of the object zero-filled. This is not specific to strings.
R..