struct 的字符串成员正在附加其他字符串成员,均使用 scanf 解析
Posted
技术标签:
【中文标题】struct 的字符串成员正在附加其他字符串成员,均使用 scanf 解析【英文标题】:String member of struct is appending other string member, both parsed with scanf 【发布时间】:2021-01-29 21:35:15 【问题描述】:我对 C 有点陌生。所以,我动态创建了一个结构数组,并希望从用户那里获取输入并存储在数组中。
struct course
char code[CODE_LENGTH];
char name[NAME_LENGTH];
int credits;
;
第二个字符串成员name
存储得很好。
第一个字符串成员 code
附加了第二个字符串成员。
程序代码:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define CODE_LENGTH 7
#define NAME_LENGTH 3
struct course *createList()
int n;
printf("Enter no. of courses you wish to take: ");
scanf("%d", &n);
struct course *courses = (struct course*)malloc(sizeof(struct course)*n);
for(int i=0;i<n;i++)
printf("Enter Course Code: ");
scanf("%s",courses[i].code);
printf("Enter Course name: ");
scanf("%s",courses[i].name);
printf("Enter no. of credits: ");
scanf("%d",&courses[i].credits);
printf("\n");
printf("%s\n%s ",courses[i].code,courses[i].name);
return courses;
int main()
struct course *c = NULL;
int credit;
c=createList();
free(c);
return 0;
输出:
Enter no. of courses you wish to take: 2
Enter Course Code: CS6101D
Enter Course name: DS
Enter no. of credits: 4
CS6101DDS
DS Enter Course Code:
如果CODE_LENGTH
是7,code
怎么能存储更多,为什么还要附加另一个字符串?
帮帮我!
【问题讨论】:
C 和 C++ 是不同的编程语言。 无关:建议使用struct course *courses = malloc(n * sizeof *courses);
而不是C中的struct course *courses = (struct course*)malloc(sizeof(struct course)*n);
,它更短更安全。
【参考方案1】:
如果
CODE_LENGTH
是 7,代码如何存储更多,为什么还要附加另一个字符串?
不能,事实上它只能存储6个字符加上空字节,你程序的不稳定行为是undefined behavior的结果。
您的代码极易受到缓冲区溢出的影响,您永远不应该在 scanf
中使用 %s
说明符,就像它一样,它并不比 gets
好,并且因为太危险且容易受到攻击而从标准中删除缓冲区溢出攻击,必须将输入限制为目标缓冲区的大小:
printf("Enter Course Code: ");
scanf("%6s", courses[i].code);// %6s, 7 - 1, last element stores null byte
printf("Enter Course name: ");
scanf("%2s", courses[i].name) //same idea
请注意,如果输入大于缓冲区的容量,剩余的字符将保留在stdin
缓冲区中,并由下一个scanf
解析,您可能需要将其清除。我刚刚回答了一个关于如何以稳健的方式仍然使用 scanf
check it out 的问题。
题外话:
在
struct course *courses = (struct course*)malloc(sizeof(struct course)*n);
您应该删除演员表,它不是必需的,并且可以隐藏分配错误。
使用变量本身来推断大小也是一个好习惯,它使代码更易于维护:
struct course *courses = malloc(sizeof *courses * n);
【讨论】:
【参考方案2】:您可能正在读取 7(或更多?)字符的字符串,例如 CS6101D
,这将需要存储 8 chars
,因为NUL 终止符'\0'
需要多一个char
,scanf
会自动添加。
因此,您的代码正试图在courses[i].code[8]
上写入,它具有超出范围的索引。这是 C 中未定义的行为,可能会导致任何结果,包括您得到的结果。
【讨论】:
以上是关于struct 的字符串成员正在附加其他字符串成员,均使用 scanf 解析的主要内容,如果未能解决你的问题,请参考以下文章
golang中struct成员变量的标签(Tag)说明和获取方式