C中的错误-表达式必须是可修改的左值C/C++(137)[重复]

2w3kk1z5  于 12个月前  发布在  C/C++
关注(0)|答案(2)|浏览(164)

此问题已在此处有答案

How can I correctly assign a new string value?(6个答案)
6天前关闭
我尝试创建一个电话簿struct,并为数组的元素赋值:

#include <stdio.h>
#include <string.h>

typedef struct
{
    char name[30];
    char number[30];
}
phonebook_record;

int main(void)
{
    phonebook_record people[2];
    people[0].name = "my_name";
    people[0].number = "+555-000-0000";
}

在赋值阶段弹出错误:

phonebook.c: In function 'main':
phonebook.c:15:20: error: assignment to expression with array type
   15 |     people[0].name = "my_name";
      |                    ^
phonebook.c:16:22: error: assignment to expression with array type
   16 |     people[0].number = "+555-000-0000";
      |                      ^

我错过了什么?这是我定义结构的方式吗?包含两个char s数组?

ddrv8njm

ddrv8njm1#

虽然可以从字符串文字initialize数组,但不能将字符串文字assignment到数组。为此,您必须使用类似strcpy的东西。
初始化:

#include <stdio.h>
#include <string.h>

typedef struct
{
    char name[30];
    char number[30];
}
phonebook_record;

int main(void)
{
    phonebook_record people[2] = {
        { .name = "my_name", .number = "+555-000-0000" }
    };
}

将字符串的值(单个字符)复制到数组中:

#include <stdio.h>
#include <string.h>

typedef struct
{
    char name[30];
    char number[30];
}
phonebook_record;

int main(void)
{
    phonebook_record people[2];
    strcpy(people[0].name, "my_name");
    strcpy(people[0].number, "+555-000-0000");
}
qjp7pelc

qjp7pelc2#

在C中,不能直接将值赋给整个数组,除非在初始化期间(即当声明对象时)。下面是一个例子:

int main(void)
{
    phonebook_record people[2] =
    {
        { "my_name",   "+555-000-0000" },
        { "my_name_2", "+555-000-0001" } 
    };
}

如果要在声明对象后更改以空结尾的字符数组的内容,可以为数组的各个元素赋值(即单个字符),或者您可以使用函数strcpy一次更改多个字符的内容。下面是一个例子:

int main(void)
{
    phonebook_record people[2];

    strcpy( people[0].name, "my_name" );
    strcpy( people[0].number, "+555-000-0000" );
}

然而,使用函数strcpy可能是危险的,因为如果目标内存缓冲区中没有足够的空间,那么你将有一个buffer overflow。因此,通常使用函数snprintf会更安全,如下所示:

int main(void)
{
    phonebook_record people[2];

    snprintf(
        people[0].name, sizeof people[0].name,
        "%s", "my_name"
    );
    snprintf(
        people[0].number, sizeof people[0].number,
        "%s", "+555-000-0000"
    );
}

如果字符串太长,函数snprintf将截断字符串,而不是溢出目标缓冲区。如果你想检测是否发生了这样的截断,你可以检查snprintf的返回值。
然而,尽管不可能在声明之外为整个数组赋值,但可以为整个struct赋值。由于两个char数组是struct的成员,因此为struct赋值将间接为两个数组的整个内容赋值。给struct赋值的一种方法是给它赋值compound literal的值。下面是一个例子:

int main(void)
{
    phonebook_record people[2];

    people[0] = (phonebook_record) { "my_name", "+555-000-0000" };
}

相关问题