arrays - 结构 C 数组的用户输入
问题描述
我正在创建一个程序,它获取用户输入并将其放入一个名为 Student 的结构中,然后返回主菜单。从主菜单中,您可以添加另一个学生。这可行,但是当我尝试打印已添加到结构数组中的所有学生数据时,它只打印添加的最后一个学生。
这是结构:
struct Student
{
char* firstName;
int age, cuid;
float GPA;
};
这就是我在 main 中为数组分配空间的方式:
struct Student* studentArray = malloc(*recordMaxPtr * sizeof(struct Student));
以下是捕获用户输入并打印数组的函数:
// Gets info and adds student to the array of structs
void addStudents(struct Student* s, int *numStudents)
{
// Allocate memory for the first name
char *firstName = (char*) malloc(25*sizeof(char));
// Gets the name of student
printf("What is the name of the student you'd like to add? ");
gets(s->firstName);
printf("\n"); // blank line
// Gets age of student
printf("How old is the student? ");
scanf("%d", &s->age);
printf("\n"); // blank line
// Gets CUID
printf("What is his / her CUID number? ");
scanf("%d", &s->cuid);
printf("\n"); // blank line
// Gets GPA
printf("What is the student's GPA? ");
scanf("%f", &s->GPA);
printf("\n"); // blank line
}
// Sorts the array and then lists all of the saved students
void printStudents(struct Student* s, int *numStudents)
{
//bsort();
for (int i = 0; i < *numStudents; i++)
{
printf("Student #%d\n", i + 1);
printf(" Student's Name: %s\n", s[i].firstName);
printf(" Age: %d\n", s[i].age);
printf(" CUID: %d\n", s[i].cuid);
printf(" GPA: %2f\n", s[i].GPA);
}
}
我曾想过尝试使用 for 循环来一次收集我需要的所有学生数据,但这是一个学校项目,我不允许这样做。我一直试图弄清楚这一点,但我在做什么时遇到了障碍。我最好的猜测是,每次您将新学生输入数组时,数据都会被覆盖,但我不知道如何解决这个问题。
解决方案
您为名字分配了内存,但没有将其保存在任何地方。您必须将地址存储到结构中。
// Allocate memory for the first name
char *firstName = (char*) malloc(25*sizeof(char));
s->firstName = firstName; // add this
为了获得更好的代码,还有一些事情要做:
- 检查是否
malloc()
成功 - 检查是否
scanf()
成功 - 替换
gets()
为fgets()
和删除换行符(gets()
具有不可避免的缓冲区溢出风险并从新的 C 规范中删除) - 删除结果的强制转换
malloc()
(c - 我是否强制转换 malloc 的结果? - 堆栈内存溢出)
推荐阅读
- mysql - INSERT INTO ... SELECT ... statement not working
- kubernetes - 缩小 kubernetes 作业,但在完成之前不要删除 pod
- android - 如何修复 MessageQueue 泄漏?
- nssm - NSSM 无法为服务设置启动参数!正在删除服务
- c# - 会话超时未命中操作过滤器
- javascript - JQuery 可调整大小的拆分器异常行为
- javascript - 返回 true 不更改按钮名称
- python - Python:使用python从一行中写入匹配的单词以数字开头
- android - 来自现有 SQLite 数据库的微调器
- javascript - 从父类扩展反应组件