【问题标题】:What's wrong with using pointer in a struct when passing it to gets()?将指针传递给gets()时在结构中使用指针有什么问题?
【发布时间】:2014-09-03 21:56:58
【问题描述】:

我有以下代码。在结构定义中,我尝试让用户输入员工的名字和姓氏。但是当我运行这个exe时,它会在输入标题后退出。有什么建议么?

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

#define NUMEMPS 10

struct Employee {
char *firstname;
char *lastname;
char *title;
int  salary;
};

int main()
{ 
 struct Employee* stuff = malloc(NUMEMPS* sizeof *stuff);
 int n,i;
 for (n=0; n<NUMEMPS;n++)
 {
  printf("Please enter number %d Employee's Last name:", n);
  fflush(stdout);
  gets(stuff[n].lastname);
  if (strlen(stuff[n].lastname) == 0)
  break;
  printf("Please enter number %d Employee's first name:", n);
  fflush(stdout);
  gets(stuff[n].firstname);
  printf("Please enter number %d Employee's title:", n);
  fflush(stdout);
  gets(stuff[n].title);
  printf("Please enter number %d Employee's salary:", n);
  fflush(stdout);
  scanf("%d", &stuff[n].salary);
  getchar();
  }
  for (i = 0;i<n;i++)
  {
  printf("{%s,%s,%s,%d}\n", 
         stuff[i].lastname,
         stuff[i].firstname,
         stuff[i].title,
         stuff[i].salary);
  }
  return 0;
  }

【问题讨论】:

  • 不要使用gets();它不再是标准 C 的一部分,并且无论任何其他问题如何,都无法安全使用。请改用fgets()getline(),记住这两者都在结果字符串中包含分隔符(换行符),而gets() 将其省略。并检查每个输入操作的结果。
  • @JonathanLeffler: [pubs.opengroup.org/onlinepubs/9699919799/functions/…(getline) 由 POSIX 定义,但不是由 C 标准定义。它可能并不存在于所有系统上——或者可能存在同名的不同函数。
  • @KeithThompson:是的;这就是为什么我把 fgets() 放在第一位的原因,尽管我承认我没有像往常一样包含 URL,也没有明确地将 getline() 称为仅限 POSIX。
  • 关于这一行: struct Employee* stuff = malloc(NUMEMPS* sizeof *stuff);这仅为 10 个指针分配空间,而不是 10 个 'struct Employee' 代码中还有一些其他问题,例如将员工数组放入堆栈,但这是第一个/主要问题。
  • 字符串的读取没有包含字符串的地方。 IE。每个员工结构中的每个字符串指针都需要一个 malloc 来预先分配一些内存来保存字符串,或者需要修改结构字段以定义一个(对于最长条目而言足够大)字符数组。自然,如果使用 malloc 方法,那么所有这些内存分配都需要被释放。

标签: c pointers struct char gets


【解决方案1】:

结构的三个char* 成员是指针,因此没有分配空间来保存任何数据。

使用当前的struct,您必须为数据再做三个分配:

struct Employee* stuff = malloc(NUMEMPS* sizeof *stuff);
stuff->firstname = malloc(101);
stuff->lastname = malloc(101);
stuff->title = malloc(101);

你可能想要的是这样的:

struct Employee {
    char firstname[101];
    char lastname[101];
    char title[101];
    int  salary;
    };

此外,顺便说一句,您必须检查您的 malloc 调用是否返回 NULL。

【讨论】:

  • 请注意,他的尺寸是您想要或认为合适的任何尺寸。我刚刚从空中选择了101(允许 100 字节的数据和一个空终止符)。
【解决方案2】:

这段代码:

struct Employee {
char *firstname;
char *lastname;
char *title;
int  salary;
};

...

 struct Employee* stuff = malloc(NUMEMPS* sizeof *stuff);

只分配足够的空间来存储单个struct Employee,即:三个指针和一个整数。 指向的字符串没有存储空间。

相反,请考虑 malloc() 将每个组成字符数据分配给 stuff-&gt;firstname(等),或修改 struct Employee 的声明以包含字符数组。

【讨论】:

  • -1 因为 malloc 不包含 struct Employee 的空间,而是包含 10 个指向 struct Employee 的指针
  • @user3629249,您没有仔细阅读答案。此答案中未提出任何代码,仅从问题中引用。 "此代码:...cited code... 仅分配"
猜你喜欢
  • 2020-04-25
  • 2017-01-22
  • 2020-05-15
  • 1970-01-01
  • 1970-01-01
  • 2017-10-02
  • 2018-04-15
  • 2021-07-17
相关资源
最近更新 更多