无法使用fgets()函数读取循环结构中的字符串

时间:2014-01-26 07:16:18

标签: c string fgets gets

我还使用fgets()gets()来获取字符串作为循环内的输入。在第一次执行时,它正常工作,但在第二次,它跳过输入步骤,然后直接进入下一行。

#include<stdio.h>
#include<conio.h>
struct student
{
    int roll,m[3];
    float avg;
    char name[30];
}s[5];
void main()
{
    int i;
    clrscr();
    printf("Enter thr student details:");
    for(i=0;i<5;i++)
    {
        printf("\nstudent[%d] name:",i+1);
        fgets(s[i].name,30,stdin);
        printf("student[%d] register number:  ",i+1);
        scanf("%d",&s[i].roll);
        printf("student[%d] marks:\n",i+1);
        scanf("%d%d%d",&s[i].m[0],&s[i].m[1],&s[i].m[2]);
        s[i].avg=(s[i].m[0]+s[i].m[1]+s[i].m[2])/3;
    }
    printf("-----------------------------------------------------------");
    printf("\n  NAME        REG.NO      AVERAGE");
    printf("\n-----------------------------------------------------------");
    printf("\n      DISTINCTION");
    for(i=0;i<5;i++)
        if(s[i].avg>74)
            printf("\n%-20s%-10d%.2f",s[i].name,s[i].roll,s[i].avg);
    printf("\n              FIRST CLASS");
    for(i=0;i<5;i++)
        if((s[i].avg<74)&&s[i].avg>50)
            printf("\n%-20s%-10d%.2f",s[i].name,s[i].roll,s[i].avg);
    printf("\n                 FAIL");
    for(i=0;i<5;i++)
        if(s[i].avg<50)
            printf("\n%-20s%-10d%.2f",s[i].name,s[i].roll,s[i].avg);
    getch();
}

3 个答案:

答案 0 :(得分:0)

Enter thr student details:
student[1] name:abcd <Enter>

fgets读取,直到达到大小限制或返回EOF或遇到新行(\n)字符。在上面的场景中,它会显示abcd并且还会读取\n,然后返回。

student[1] register number:  12<Enter>
student[1] marks:
12 13 14<Enter>

现在,您正在使用scanf来阅读这些数字。 scanf %d返回,直到遇到号码或看到EOF为止。它会忽略所有新行字符。

完成上述两个步骤后,您会在输入流中留下额外的\n。(因为scanf实际上并未读取它。)

现在,当您有fgets的下一个电话时,首先已经有\n。它返回那里,实际上没有提示输入下一个名字。

解决方案:

阅读标记后放置getch()。这会从流中删除前导\n。 或者,使用scanf本身读取名称。

scanf("%s", s[i].name);

答案 1 :(得分:0)

scanf("%d%d%d") Enter '\n'留在stdin中。以下fgets()只会读取"\n"

最佳解决方案是使用fgets()/sscanf()组合。强大的代码检查返回结果。

{
  char buf[100];
  printf("\nstudent[%d] name:",i+1);
  if (fgets(s[i].name, sizeof s[i].name, stdin) == NULL) 
    Handle_EOF();
  printf("student[%d] register number:  ", i+1);
  if (fgets(buf, sizeof buf, stdin) == NULL) 
    Handle_EOF();
  if (sscanf(buf, "%d", &s[i].roll) != 1) 
    Handle_InputError();
  printf("student[%d] marks:\n",i+1);
  if (fgets(buf, sizeof buf, stdin) == NULL) 
    Handle_EOF();
  if (sscanf(buf, "%d%d%d", &s[i].m[0], &s[i].m[1], &s[i].m[2]) != 3)
    Handle_InputError();
  s[i].avg = (s[i].m[0] + s[i].m[1] + s[i].m[2])/3;
}

答案 2 :(得分:0)

@chux告诉

scanf离开&#39; \ n&#39;在stdin(内存缓冲区)中,fgets()取值,直到有一个&#39; \ n&#39;在缓冲区中,为了清除缓冲区,在fflush(stdin);语句之前使用了语句fgets()