使用 gets() 在结构中获取输入时出错

Error in getting input in structure using gets()

我正在制作一个程序以在教师结构中输入,但存在未知的 运行 时间错误,这是代码 -

#include <stdio.h>
#include <conio.h>

struct Teacher
{
 char Name[30];
 char Qualifications[20];
 int experience_year;
}th[10];

void teacher()
{    
 int t,i;
 printf("Enter how many teachers are in department\n");
 scanf("%d",&t);
 for(i=1;i<=t;i++)
 {       
   printf("Enter name of teacher : ");
   gets(th[i].Name);
   printf("Enter qualification of teacher : ");
   gets(th[i].Qualifications);
   printf("Enter experience_year of teacher : ");
   scanf("%d",&th[i].experience_year);
 }
 for(i=1;i<=t;i++)
 {
   printf("Details of %d teacher\n",i);
   printf(th[i].Name);
   printf(" ");
   printf(th[i].Qualifications);
   printf(" ");
   printf("%d",th[i].experience_year);
   printf("\n");
 }
}   
int main()
 {
   teacher();
   return 0;
 }

输出为-

Enter number of teacher
1
Enter teachers name : Enter qualification of teacher :

如何获取老师的姓名(输入)..错误是什么?

使用这个:

getchar();

之前

 gets(th[i].Name);

消耗前导空格和换行符,这些空格和换行符由于先前的语句而留在缓冲区中。

此外,我会推荐 fgets,它比 gets 更安全,因为:

fgets(th[i].Name,30,stdin);

fgets(th[i].Qualifications,20,stdin);

Why gets is dangerous

当您输入教师人数 t 时,您在保留在缓冲区中并被接受为 gets 语句输入的整数后输入 \n。因此在输入整数后使用getchar来解决问题。

int t,i;
printf("Enter how many teachers are in department\n");
scanf("%d",&t);
getchar();

并在 for 循环中的 scanf 之后添加另一个 getchar。

scanf("%d",&th[i].experience_year);
getchar();

首先提醒一下好的和坏的做法:

  • 你不能使用 gets - 只有 fgets 是好的
  • 你不能混用 [f]gets[f]scanf - 只坚持一种输入模式

现在让我们认真一点。

gets 尝试在您的输入数组中放入与输入流中存在的字符一样多的字符:它曾经是无数内存违规的原因。 永远不要使用它并且只在你想要处理行模式输入时使用fgets(但不要忘记fgets的输入保持终止\n)

[f]scanf 用于空白分隔字段。也就是说,它读取一个字段直到下一个空白字符(至少 space、制表符、\r\n),然后 将其留在输入流 中。您可以尝试使用 fgets 跳过它并丢弃读取的内容,或者逐字符读取直到 \n。避免使用它,因为你得到了很多 不好的 答案,建议使用一个 getchar()。这始终是第一次尝试,它一直有效,直到您在换行符之前获得带有(不可见)spaces 的输入 - 只需尝试一下,您就会明白为什么这是一个错误的解决方案。

那你该怎么办?如果输入是面向行的,只使用 fgets,然后用 sscanf 解码输入值:

void teacher()
{    
 int t,i;
 char line[16];
 printf("Enter how many teachers are in department\n");
 fgets(line, sizeof(line), stdin);
 sscanf(line, "%d",&t);
 for(i=1;i<=t;i++)
 {       
   printf("Enter name of teacher : ");
   fgets(th[i].Name, 30, stdin);
   printf("Enter qualification of teacher : ");
   fgets(th[i].Qualifications, 30, stdin);
   printf("Enter experience_year of teacher : ");
   fgets(line, sizeof(line), stdin);
   sscanf(line, "%d",&th[i].experience_year);
 }
 ...

并且在真正好的实践中(实际上所有可以在实际工作中使用的东西)你应该总是测试输入函数的结果(留作 [=上面代码中的 53=] :-) )

使用:

#include < stdio.h > 
#include < conio.h >
void main()
{
    char name[3][100], add[3][100];
    int i;
    printf("ENTER YOUR DETAIl:");
    for (i = 0; i < 3; i++) {
        fflush(stdin);
        printf("ENTER NAME:  ");
        gets(name[i]);
        printf("ENTER ADDRESS: ");
        gets(add[i]);
    }
    for (i = 0; i < 3; i++) {
        printf("\n___________________\n");
        printf("\nNAME:%s", name[i]);
        printf("\Address:%s", add[i]);
        printf("\n___________________\n");
    }

    getch();
}

你可以在c编程中使用这种方式。如果您的程序不将带空格的字符串作为多字符串类型输入的输入。

fflush(stdin);

此函数将清除您的输入缓冲区。

使用

fflush(stdin);

在每个 gets()

之前