2

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

Wok
  • 4,956
  • 7
  • 42
  • 64
alfo
  • 21
  • 2
  • 2
    Read this: http://stackoverflow.com/questions/2124935/c-strings-confusion/2125429#2125429 – t0mm13b Sep 26 '10 at 20:35
  • 2
    Arrays are not pointers ... and pointers are not arrays ... read this: http://c-faq.com/aryptr/index.html – pmg Sep 26 '10 at 20:43

7 Answers7

7

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
  • 476,176
  • 80
  • 629
  • 1,111
  • 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 Sep 26 '10 at 20:32
  • 3
    I'd use a `const char*` when dealing with string literals. – Matthew Sep 26 '10 at 20:34
  • @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 Sep 26 '10 at 21:59
4

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
  • 169
  • 4
2

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
  • 878
  • 6
  • 14
1

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
  • 119,563
  • 19
  • 122
  • 198
  • 1
    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.. GitHub STOP HELPING ICE Sep 27 '10 at 02:36
0

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

Christian Ammer
  • 7,464
  • 6
  • 51
  • 108
0

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

dgnorton
  • 2,237
  • 16
  • 12
0

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
  • 2,443
  • 3
  • 24
  • 39
  • 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 Sep 27 '10 at 00:02
  • "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 = &x ; Here, &x is [what my colleagues and I call] a pointer constant--it is a value which is an address of some other place in memory, and it cannot be changed. It is not a pointer. Aside from that, what issues are there with my post? – Kizaru Sep 27 '10 at 00:21
  • The problem is that the expression `str` isn't always treated as a pointer. Here's the relevant paragraph (section 6.3.2.1, para 3) " **Except when it is the operand of the sizeof operator or the unary & operator, or is a string literal used to initialize an array** , an expression that has type ‘‘array of type’’ is converted to an expression with type ‘‘pointer to type’’ that points to the initial element of the array object and is not an lvalue. If the array object has register storage class, the behavior is undefined." Emphasis mine. – John Bode Sep 27 '10 at 00:42
  • Also, what you call pointer constants are more commonly known as rvalues (i.e. the value of an expression). – dreamlax Sep 27 '10 at 00:53