在C语言中将字符串赋值给结构体中的元素

5

我有这个结构:

typedef struct SM_DB
{
    LIST_TYPE           link;
    char                name[SM_NAME_SIZE];
} SM_DB_TYPE;

我想给它的'name'赋值一个字符串。我是这样做的:

SM_DB_TYPE one;
one.name = "Alpha";

然而,编译后我遇到了一个错误:"error C2106: '=' : left operand must be l-value"。我希望这很明显。有人知道我哪里做错了吗?
谢谢。

你不能将字符串赋值给字符数组。 - squiguy
1
你可以这样做,但必须同时完成,即 char name[SM_NAME_SIZE] = "Alpha"; - Gillespie
5个回答

6

在声明字符串时,您只能分配值。您不能稍后使用=进行分配。

您必须使用strcpy()函数。


6
假设SM_NAME_SIZE足够大,您可以这样使用strcpystrcpy(one.name, "Alpha"); 在执行strcpy之前,请确保目标具有足够的空间来容纳字符串,否则会发生缓冲区溢出。
如果想要更加安全,您可以这样做:
if(!(one.name = malloc(strlen("Alpha") + 1))) //+1 is to make room for the NULL char that terminates C strings
{
      //allocation failed
}
strcpy(one.name, "Alpha");  //note that '\0' is not included with Alpha, it is handled by strcpy
//do whatever with one.name
free(one.name) //release space previously allocated

请确保在使用malloc时释放 one.name,以便不浪费内存。


就我所知,我们无法为数组分配内存。是这样吗?但你的答案仍然给了我一种方法。 - phougatv

2
使用strcpystrncpy在C语言中赋值字符串。

或者如果您能使用它们,可以使用strcpy_s或strncpy_s。 - Glenn
1
或者,如果您知道源字符串的长度,请使用memmove()memcpy() - 如果您不知道源字符串的长度,那么如何确定将字符串安全地复制到目标中。 - Jonathan Leffler

2

C没有内置的字符串类型。您必须使用字符数组来保存字符串。

由于C也不允许将一个数组赋值给另一个数组,因此您必须使用标准C库中的各种函数将数组元素从一个数组复制到另一个数组,或者自己编写循环来完成。虽然有时有理由编写自己的循环,但使用标准C库函数要好得多。

对于与char类型一起使用的标准ANSI类型字符串,有大量以str开头的函数,例如用于复制或比较字符串的函数strcpy()strcmp()。还有另一组函数,您可以在其中指定要复制或比较的最大字符数,例如strncpy()strncmp()

C中的字符串是由二进制零字符终止的字符数组。因此,如果您使用常量字符串,例如“Constant”,这将创建一个字符数组,每个字符都有一个元素,再加上一个附加元素,用于零终止符。

这意味着在调整char数组的大小时,您还必须记住添加一个额外的数组元素来容纳零终止符。

strncpy()函数将把一个char数组复制到另一个char数组中,直到达到指定的最大字符数或找到零终止符为止。如果达到了最大字符数,则目标数组将不会以零终止符结尾,因此这是需要注意的地方。

char  one[10];
char  two[20];
strncpy (one, "1234567", 10);  // copy constant to the char buffer max of 10 chars
one[9] = 0;   // make sure the string is zero terminated, it will be this is demo
strcpy (two, one);
strcat (two, " suffix");    // add some more text to the end

此外,还有用于处理与UNICODE一起使用的宽字符的功能。


1

使用:

strcpy(one.name, "Alpha"); //Removed null byte (Read first comment by shf301)

替代方案:

typedef struct SM_DB  
{
    LIST_TYPE           link;
    char*               name;   
} SM_DB_TYPE;

SM_DB_TYPE one;
one.name = malloc(sizeof(char) * (strlen("Alpha") + 1); //Allocate memory
if (!one.name) {
   /* Error handling */
} else {
    strcpy(one.name, "Alpha");
}

你不需要使用 '\0'。字符串常量在结尾处隐式地有一个空的零。"Alpha\0"创建的字符串带有两个尾随的零。 - shf301
你不觉得 sizeof(char) 有点多余吗?因为一个 char 只有一个字节。除非我想错了,否则这不就是在说 malloc(1 * strlen("Alpha\0")) 吗? - Keith Miller
@KeithMiller 这只是增加了可读性(特别是考虑到读者的专业水平可能会有很大差异) - check123
1
当你移除了\0时,strlen的值将比malloc短一个字节... - Bo Persson
@BoPersson 我犯了一些非常愚蠢的错误。感谢您的跟进。 :) - check123

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接