如何修复此左值警告?

时间:2010-07-20 18:22:17

标签: c++ arrays

我的代码是:

void main() {
 person student[10];

 student[0].names[0] = 'C';
 student[0].names[1] = 'a';
 student[0].names[2] = 'm';
 student[0].names[3] = 'i';
 student[0].ages = 16;
 student[0].sex[0] = 'F';
 student[0].sex[1] = 'e';
 student[0].sex[2] = 'm';
 student[0].sex[3] = 'a';
 student[0].sex[4] = 'l';
 student[0].sex[5] = 'e';
 student[0].month = 8;
 student[0].day = 2;
 student[0].year = 1993;
}

所有“学生”都有下划线说明表达必须是可修改的左值。我该如何解决这个问题?

person

typedef struct person 
{ 
char names[20][10]; 
char sex[6][10]; 
int ages[10]; 
int month[10]; 
int day[10]; 
int year[10]; 
} person;

6 个答案:

答案 0 :(得分:9)

数组用法

你说你有:

typedef struct person {
    char names[20][10];
    char sex[6][10];
    int ages[10];
    int month[10];
    int day[10];
    int year[10];
} person;

不需要[10]。您已经在person student[10]声明中拥有该声明,这是[10]的正确位置。删除无关的数组:

typedef struct person {
    char name[20];
    char sex[6];
    int age;
    int month;
    int day;
    int year;
} person;

字符串处理

此外,您的字符串不是以null结尾。在C字符串中,需要在末尾添加一个额外的'\0'字符来指示字符串结尾的位置。例如,您的姓名分配应为:

student[0].name[0] = 'C';
student[0].name[1] = 'a';
student[0].name[2] = 'm';
student[0].name[3] = 'i';
student[0].name[4] = '\0';

实际上,有一种更简单的方法来分配字符串,而不是一次一个字符。 strcpy 函数将一次复制整个字符串:

strcpy(student[0].name, "Cami");

或者,最简单的选择是使用C ++中提供的字符串类。它使字符串处理比操作字符数组的C方式更容易。使用字符串类,您的代码将如下所示:

// Modified struct declaration.
typedef struct person {
    std::string name;
    std::string sex;
    int         age;
    // ...
} person;

// Modified assignment.
student[0].name = "Cami";

答案 1 :(得分:2)

为什么要将names定义为包含10列的2D数组?你认为你需要这样做是因为你要创建10个person对象吗?

如果是这种情况,请记住:当您创建person结构时,您只需为该一个对象定义成员变量。

因此,如果您的person只有一个名称和一个性别(需要定义6个字符),那么只需使用那么多,因为当您创建10个人物对象(person student[10];)时,您正在创建10个person对象的唯一副本!因此person[0].nameperson[1].name不同。

因此,我们首先在person中为一个人定义成员变量:

struct person 
{ 
char names[20]; 
char sex[6]; 
int age; 
int month; 
int day; 
int year; 
};

然后在代码中详细说明为名称指定字符。

现在,这是一个好主意,因为names未初始化。所以student[0].names[4]是未定义的(当它应该是一个空字符来终止它)。您考虑过使用std::string吗?毕竟你有C ++!

另外,你会注意到我已经改变了person('struct person ... instead of typedef ..`)的定义,因为这就是你需要在C ++中做的所有事情。 / p>

的变化:

考虑以下person结构:

#include <string>
struct person 
{ 
    std::string person;
    std::string sex;
    int age; 
    int month; 
    int day; 
    int year; 
};

现在,您可以通过以下方式分配字符串:

person student[10];
student[0].name = "Cami";
student[0].sex = "Female";
student[0].age = 16;
student[0].month = 8;
student[0].day = 2;
student[0].year = 1993;

并且假设你想用键盘输入的for循环填充它 - 现在更容易了:

#include <iostream>
for(int i = 0; i < 10; ++i)
{
 std::cin>>student[i].name;
 std::cin>>student[i].sex;
 std::cin>>student[i].age;
 std::cin>>student[i].month; 
 std::cin>>student[i].day; 
 std::cin>>student[i].year; 
}

答案 2 :(得分:2)

student[0].names[0]的类型为(char *),无法分配。

您需要分配到student[0].names[0][0](或更改names的定义)

答案 3 :(得分:1)

不可修改的lvalue是可寻址的,但不可分配。

话虽如此,你打算让struct成为一堆不同名字的容器吗?

你真正需要的是一个struct数组来为人们创建一个容器。 (即struct person p[10];

答案 4 :(得分:1)

[10]结构的每个字段都不需要额外的person。这使得这些字段本身成为数组。例如,你想要一个由10个人组成的阵列,每个人都有一个年龄。你现在拥有的是一群十人,每人有十个年龄。

student数组的每个元素都有自己person中定义的每个字段的实例,因此这些字段本身不必是数组。

答案 5 :(得分:0)

  1. 如果此文件中未定义person,则可能未包含正确的头文件。

  2. 不要忘记将\0添加到字符串

  3. 如果名称是二维数组,则不应该是:

    姓名[0] [0] ='J';
    names [0] [1] ='i';
    names [0] [2] ='m';
    names [0] [3] ='\ 0';