C语言中结构的意外行为

时间:2014-01-27 09:27:27

标签: c struct scanf turbo-c++

我在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时,会显示姓氏,但是当所有人都被声明为字符时,它就无效了。

4 个答案:

答案 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;
}