【问题标题】:How to assign a value to a struct that is returned through a function in C如何将值分配给通过 C 中的函数返回的结构
【发布时间】:2015-12-03 01:36:15
【问题描述】:
 extern int ID; // student ID number
    struct personalDetails det; // pD
    struct classRecords rec; // cR
    struct student st1; // student 1
    struct student st2; // student 2
    struct student st3; // student 3
    struct student st4; // student 4
    struct student st5; // student 5

    char pD[30]; // for storing values that will be assigned to personalDetails
    double cR; // for storing values that will be assigned to classRecords

    struct student studentID(int id) { // identifies student by ID
    if (id == 1) {
            struct student x = st1;
            return x;
    }
    else if (id == 2) {
            struct student x = st2;
            return x;
    }
    else if (id == 3) {
            struct student x = st3;
            return x;
    }
    else if (id == 4) {
            struct student x = st4;
            return x;
    }
    else if (id == 5) {
            struct student x = st5;
            return x;
    }
    }

我需要函数 updateName() 为“name”分配一个值,该值是另一个 struct personalDetails 中的值。

 void updateName() {
    printf("Enter student's name\n");
    scanf("%s", pD);

    studentID(ID).det.name = pD;

我目前收到此错误:

operations.c: In function ‘updateName’:
    operations.c:55:24: error: lvalue required as left operand of assignment
     studentID(ID).det.name = pD;

请告诉我如何解决这个问题,提前谢谢!

编辑 1:这是为感兴趣的人准备的结构定义。

struct personalDetails {
        char *name;
        char *phoneNum;
        char *address;
};

struct classRecords {
        double assignment;
        double midterm;
        double finalMark;
        double total;
};

struct student{
        struct personalDetails det;
        struct classRecords rec;
};

感谢您的回答,strcpy 摆脱了编译错误,但现在当我输入“名称”的值时,我得到一个“分段错误”。有谁知道为什么?

【问题讨论】:

  • typedef 是你的朋友 ;)

标签: c struct


【解决方案1】:

studentID(ID) 返回存储数据的结构的副本,您需要将其存储到另一个结构中。您可能希望返回一个指向它的指针并使用以下语法:

strcpy(studentID(ID)->det.name, pD);

但你也应该注意潜在的缓冲区溢出:例如,scanf 格式为%s 不知道pD 指向的数组的大小。你应该这样写:

scanf("%29s", pD);

但是告诉scanf 缓冲区大小非常麻烦,因为大小信息必须在格式字符串中硬编码,并且如果您稍后更改数组pD 的实际大小,可能会变得不同步。 scanf 很难正确使用。

【讨论】:

  • @artm: scanf 几乎总是错误的 ;-) 我更新了我的答案以反映这一点。
【解决方案2】:

C 不允许您使用等号运算符直接分配字符串。您可以使用 strncpy(包括 string.h)。通过在终端中输入“man strncpy”或谷歌搜索了解该功能。

【讨论】:

  • 即使阅读了strncpy的手册,OP也不应该使用它,它太容易出错了。
【解决方案3】:

您尚未出示您的struct student 声明;但看起来name 是一个字符数组。那么,

scanf("%s", &pD);不正确,应该是scanf("%s", pD);,因为pD已经是字符串字符的地址了。

另外,studentID(ID).det.name = pD; 也是不正确的,你不能对字符串变量使用直接赋值,而是使用strcpy

【讨论】:

  • 严格来说pD不是指针而是数组。它将被转换为用作函数参数的指针。 (更一般地,对于除sizeof& 之外的运算符的操作数用于获取地址)
  • strcpy 在编译时消除了错误,但是现在当我运行我的程序时,在输入“名称”的值时出现“分段错误”。你知道这是为什么吗?
  • SIGSEGV 通常意味着您正在取消引用未初始化的指针,或者您正在访问越界的数组。请检查student 结构中的name 数据成员。
  • @artm 我不太清楚你所说的取消引用一个未初始化的指针是什么意思?但我知道它没有越界
【解决方案4】:

我猜你想要这样的东西。使用指针。

extern int ID; // student ID number
struct personalDetails det; // pD
struct classRecords rec; // cR
struct student st1; // student 1
struct student st2; // student 2
struct student st3; // student 3
struct student st4; // student 4
struct student st5; // student 5

    char pD[30]; // for storing values that will be assigned to personalDetails
    double cR; // for storing values that will be assigned to classRecords

struct student *studentID(int id) { // identifies student by ID
    if (id == 1) {
            return &st1;
    }
    else if (id == 2) {
            return &st2;
    }
    else if (id == 3) {
            return &st3;
    }
    else if (id == 4) {
            return &st4;
    }
    else if (id == 5) {
            return &st5;
    }
}

 void updateName() {
    struce student *s;
    printf("Enter student's name\n");
    scanf("%29s", pD);

    s = studentID(ID);
    s->det.name = malloc(strlen(pD) + 1);
    strcpy(s->det.name, pD);
}

我不确定这是否正确,因为我不知道struct student 的定义,但是请不要做将固定数组(指向第一个元素的指针)分配给多个结构。

【讨论】:

  • 抱歉,我最近才开始使用 C。但是每当我使用 -> 时,我都会收到一个不同的错误错误:'->' 的无效类型参数(有 'struct student')strcpy(studentID( ID)->det.name, pD);
  • @rsorce 将* 添加到studentID() 的返回类型中,并像我一样将其设为指针。
  • 我更新了我的代码。在将字符串复制到那里之前,您必须分配一些缓冲区。
猜你喜欢
  • 2021-03-04
  • 2012-09-26
  • 2022-10-14
  • 1970-01-01
  • 1970-01-01
  • 2011-05-24
  • 1970-01-01
  • 2021-03-25
  • 1970-01-01
相关资源
最近更新 更多