struct 的字符串成员附加其他字符串成员,均使用 scanf 解析
String member of struct is appending other string member, both parsed with scanf
我对 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
怎么能存储更多,为什么要附加另一个字符串?
帮帮我!
If CODE_LENGTH
is 7 how can code store more than that and why is it appending the other string?
它不能,事实上它只能存储 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
注意如果输入大于buffer所能接受的,剩余的字符会保留在stdin
buffer中,被下一个scanf
解析,可能需要clear它。我刚刚回答了一个关于如何以稳健的方式做到这一点的问题,仍然使用 scanf
check it out.
Off-topic:
在
struct course *courses = (struct course*)malloc(sizeof(struct course)*n);
您应该删除强制转换,它不是必需的并且可以隐藏分配错误。
使用变量本身来推断大小也是一个好习惯,它使代码更易于维护:
struct course *courses = malloc(sizeof *courses * n);
您可能正在读取一串 7(或更多?)字符,例如 CS6101D
,这将需要 8 chars
将被存储,因为您还需要一个 char
作为 NUL 终止符 '[=13=]'
,scanf
将自动添加。
因此,您的代码正试图在 courses[i].code[8]
上写入,它有一个越界索引。这是 C 语言中未定义的行为,可能导致任何结果,包括您得到的结果。
我对 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
怎么能存储更多,为什么要附加另一个字符串?
帮帮我!
If
CODE_LENGTH
is 7 how can code store more than that and why is it appending the other string?
它不能,事实上它只能存储 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
注意如果输入大于buffer所能接受的,剩余的字符会保留在stdin
buffer中,被下一个scanf
解析,可能需要clear它。我刚刚回答了一个关于如何以稳健的方式做到这一点的问题,仍然使用 scanf
check it out.
Off-topic:
在
struct course *courses = (struct course*)malloc(sizeof(struct course)*n);
您应该删除强制转换,它不是必需的并且可以隐藏分配错误。
使用变量本身来推断大小也是一个好习惯,它使代码更易于维护:
struct course *courses = malloc(sizeof *courses * n);
您可能正在读取一串 7(或更多?)字符,例如 CS6101D
,这将需要 8 chars
将被存储,因为您还需要一个 char
作为 NUL 终止符 '[=13=]'
,scanf
将自动添加。
因此,您的代码正试图在 courses[i].code[8]
上写入,它有一个越界索引。这是 C 语言中未定义的行为,可能导致任何结果,包括您得到的结果。