In C, why can't I assign a string to a char array after it's declared?
Asked Answered
E

6

14

This has been bugging me for a while.

struct person {
       char name[15];
       int age;
};
struct person me;
me.name = "nikol";

when I compile I get this error:

error: incompatible types when assigning to type ‘char[15]’ from type ‘char *’

am I missing something obvious here?

Excommunicatory answered 1/11, 2014 at 21:38 Comment(3)
Are you asking how to do the initialization? struct person me = {"nikol", 3}; should work.Adversary
Similar: #14827452Rheum
this one too. Disclaimer: My answerSense
C
23

Arrays are second-class citizens in C, they do not support assignment.

char x[] = "This is initialization, not assignment, thus ok.";

This does not work:

x = "Compilation-error here, tried to assign to an array.";

Use library-functions or manually copy every element for itself:

#include <string.h>
strcpy(x, "The library-solution to string-assignment.");
Carouse answered 1/11, 2014 at 21:45 Comment(1)
I mixed up initialization and assignment, sorry. Yes, this solves it, thank you. I was led to the wrong path by a example from the teacher (which I now see is wrong).Excommunicatory
S
9

me.name = "nikol"; is wrong !! you need to use strcpy()

when you do x = "Some String", actually you are putting the starting address of the static string "Some String" into variable x. In your case, name is a static array, and you cannot change the address. What you need, is to copy your string to the already allocated array name. For that, use strcpy().

Sense answered 1/11, 2014 at 21:40 Comment(0)
I
3

First of all, you need to know the following points:

  • In C, text strings are just arrays.
  • In C, array variables are basically just pointers.

So, char mytext[12]; is essentially just declaring a char pointer called mytext that stores the address of the first (zero'th) element of the array/string.

This code is therefore valid:

#include <stdio.h>
int main(int argc, char *argv[])
{
    const char a[] = "Hello";
    const char *b = a;
    printf("%s\n", b);
    return 0;
}

The important thing to note here is that re-assigning b doesn't change the contents of whatever it points to - it changes the thing that it points to.

However, there are cases where arrays and pointers behave differently. In the example above, a cannot be reassigned. If you try, you'll get an error.

To go back to you original example, this structure:

struct person{
    char name[15];
    int age;
};

...can be thought of as a 19-byte structure* of which the first 15 bytes are earmarked for storing a string. The name attribute stores the address of the first byte, so you know where those 15 bytes live in memory - you just need to write something useful into them.

This is where functions such as sprintf() or strcpy() come into play - they copy data into the address defined by name rather than re-assigning name itself.

* Assuming that sizeof(int) is 4 and the structure is not padded, of course...

Intisar answered 1/11, 2014 at 22:4 Comment(7)
the size of the example struct is 20 Bytes. There is a padding byte between the array and the int.Unwished
You are indeed correct - I shall edit my answer accordingly.Intisar
Actually, I was right the first time - it's 19 bytes without padding, as I said originally.Intisar
@Martin James I didn't say that they were identical (hence why I emphasised the word basically in my second bullet-point, and pointed out that "there are cases where arrays and pointers behave differently" later on), but please feel free to edit the post if you think that the answer I gave could be more clear on this point.Intisar
You are off to a really bad start when you do not clearly differentiate between arrays and pointers. And in C strings are 0-terminated sequences.Carouse
@Carouse I do know the difference now. Thanks for pointing it outExcommunicatory
@KokNikol: Actually, I meant GoBusto, as his post does not really reflect that. Yes, he later mentions one difference, but that's too little (there are more) and too late (he sets the tone at the start, and too many will miss that).Carouse
S
0

You first must understand how memory assignment work in array.

When you declare the name of an array, that name actually works as pointer and point to the first element of the array.

struct person {
       char name[15];
       int age;
};

Here name is pointing to the memory address of first element of array i.e. name[0]. You have declare the character array so the each block of memory have 1 byte of size. And name is also pointing to the 1 byte of memory.

struct person me;
me.name = "nikol";

me.name = "nikol"; won't work. You are assigning 5 byte of data to 1 byte of storage and also without dereferencing the the pointer variable. For better understanding try this code

struct person me;
*me.name = 'n';

Here I have deference the pointer name and assigned 1 byte of data. This code will work perfectly fine

printf("%c" , me.name[0]);

Output will be n.

This is why we have to use strcpy() function. Strcpy() assign the each character of the string constant to the each block of memory of the array. This is why it will work.

strcpy(me.name , "nikol");
Sforza answered 23/7, 2020 at 12:18 Comment(0)
T
-1

Use strcpy() function (of string.h library) :)

main(){
struct person{
       char name[15];
       int age;
};
struct person me;
strcpy(me.name,"nikol");
}
Tacky answered 1/11, 2014 at 21:54 Comment(1)
FYI: string.h is a header, not a library.Graze
S
-1

You are trying to change the memory address of an array pointer (by giving me.name = "nikol") which is impossible. Name of array (me.name) is a fixed pointer and cannot be changed to point to a new location of string ("nikol") because memory address of an array pointer is on the first member of that array. If you want to assign a string after declared (me.name = "nikol"), use external pointer *name instead because external pointer floats outside array so its value can be changed on-the-fly.

struct person {
       char *name;
       int age;
};
struct person me;
me.name = "nikol"; // no error
Sculptor answered 10/9, 2018 at 20:45 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.