我在C编程中编写了以下代码(使用Turbo c ++)。
#include<stdio.h>
struct test
{
char fname[10];
char age[2];
char lname[10];
}s1[10];
int main()
{
int i;
for(i=0;i<3;i++)
{
printf("enter the first name : ");
scanf("%s",s1[i].fname);
printf("enter the last name : ");
scanf("%s",s1[i].lname);
printf("enter the age : ");
scanf("%s",s1[i].age);
}
for(i=0;i<3;i++)
{
printf("\n %s %s age= %s",s1[i].fname,s1[i].lname,s1[i].age);
}
getch();
return 0;
}
我按要求输入了输入。但是打印结果时发现姓氏(lname)丢失了。
你能帮我解决一下这种意想不到的结构行为吗? (请忽略价值[10],声称为字符串等的年龄,就像我为自己的目的所做的那样)
请注意:当我将年龄宣布为“int
”并使用%d
时,会显示姓氏,但是当所有人都被声明为字符时,它就无效了。
答案 0 :(得分:3)
char age[2];
太小了。如果输入正好2个字符,scanf
会将终止字符串写入lname[0]
,因为在这种特定情况下,两个数组之间的内存是连续的。
因此printf
将看到一个空数组,结果将是您观察到的结果
答案 1 :(得分:1)
更改
char age[2];
到
char age[4];
字符串需要额外的空格来终止空字符。
答案 2 :(得分:1)
正如其他人所指出的那样,问题是scanf
上有缓冲区溢出。
如何解决:
解决方案不只能增加缓冲区大小。解决方案是完全防止溢出。
增加缓冲区大小:
char age[3+1]; /* 3 for digits, +1 for NUL char */
指定要读取的最大字符数:
scanf("%3s", s1[i].age);
但由于您只阅读字符串,我建议使用fgets
代替:
fgets( s1[i].age, 4, stdin);
对所有字段执行此操作。甚至更好:将常量用于缓冲区大小。
答案 3 :(得分:0)
新行字符将作为scanf()的第二个输入插入;即:您对s1和s2的输入是: TEST1 TEST2 然后s1 =“test1”,s2 =“\ n”
所以在你的情况下你应该使用gets()函数而不是scanf()。并且您的字符串大小将是您要输入的字符数加1,因为每个字符串将在末尾添加额外的终止字符('\ 0')。即:如果你想在char s1 [SIZE]中输入5个字符;然后SIZE必须是6.按照这些说明操作。希望它有助于解决这个问题。或者你可以运行:
#include<stdio.h>
struct test
{
char fname[10];
char age[3]; // for maximum 2 digits
char lname[10];
} s1[10];
int main()
{
int i;
for(i=0; i<3; i++)
{
printf("enter the first name : ");
gets(s1[i].fname);
printf("enter the last name : ");
gets(s1[i].lname);
printf("enter the age : ");
gets(s1[i].age);
}
for(i=0; i<3; i++)
{
printf("\n %s %s age= %s",s1[i].fname,s1[i].lname,s1[i].age);
}
getch();
return 0;
}