fgets()无法按预期运行

时间:2017-06-04 20:57:24

标签: c scanf fgets

这是我的代码

int main(){
   int N,i,radius,diameter,count =0;
   char str[20];
   char color[N][20];
   printf("Get the num : ");
   scanf("%d",&N);

   printf("Enter the mesage\n");
   for(i=0;i<N;i++){
      fgets(color[i],20,stdin);
   }
   for(i=0;i<N;i++){
      printf("%s",color[i]);
  }
  return 0;
}

鉴于输入是:

N = 3
red 50,
50 green,
blue 50

这里的问题是fgets for循环只有N为3才执行两次。如果我评论scanf语句,则不会出现此问题。有人可以解释一下导致这个问题的原因以及如何解决这个问题吗?

3 个答案:

答案 0 :(得分:1)

经过几个小时的抓挠,我意识到以下几点:

  • 避免使用scanf。管理缓冲区溢出并不容易。
  • 始终尝试使用fgets获取用户输入。

请在此处试用此代码:

#include<stdio.h>
#include<stdlib.h>
int main(){
   int N,i,radius,diameter,count =0;
   char str[20];

   printf("Get the num : ");

   char buffer[64];
   fgets(buffer, 64, stdin);
   N = strtoul(buffer,NULL,10); 
   char color[N][20];

   printf("%d\n",sizeof(color));

   printf("Enter the mesage\n");

   for(i=0;i<N;i++){
      fgets(color[i],20,stdin);
      if(color[i][strlen(color[i])-1]=='\n'){

     color[i][strlen(color[i])-1]='\0';
  }
  else{

     while((getchar())!='\n');//this is just to prevent an overflow for the size of char arrays
  }

   }
   for(i=0;i<N;i++){
      printf("%s\n",color[i]);
  }
  return 0;
}

请注意,我首先在char数组中输入一个数字。使用strtoul将其转换为数字(字符串为unsigned long)。现在在for循环中我再次使用fgets来获取输入。问题是,如果输入大于19个字符的字符串,剩下的部分将留在输入缓冲区内,并应分配给后续输入。为了管理我在while循环中使用了getchar,它消耗了输入流中所有不必要的字符和换行符。避免使用fflush,因为它可能会导致未定义的行为,如此处所述

- fflush(stdin) function does not work

- http://www.geeksforgeeks.org/clearing-the-input-buffer-in-cc/

另请注意,您使用的是可变长度数组,这可能并不总是一个不错的选择。较旧版本的c编译器禁止它们。你在初始化N之前先声明了颜色[N] [20]。这是错误的。

我建议你也读这个

- C - scanf() vs gets() vs fgets()

答案 1 :(得分:0)

使用 scanf 后,您需要清理缓冲区。我建议永远不要使用 scanf ,只需使用 fgets ,然后将输出转换为数字:

int main(){
   int N,i,radius,diameter,count =0;
   char str[20];
   char color[N][20];
   printf("Get the num : ");

   char buffer[64];
   fgets(buffer, 64, stdin);
   N = atoi(buffer); // you need to include stdlib.h

   printf("Enter the mesage\n");
   for(i=0;i<N;i++){
      fgets(color[i],20,stdin);
   }
   for(i=0;i<N;i++){
      printf("%s",color[i]);
  }
  return 0;
}

答案 2 :(得分:-2)

由于这个参考: https://www.tutorialspoint.com/c_standard_library/c_function_fgets.htm 这是正确的:

int _tmain(int argc, _TCHAR* argv[])
{
    int N, i, radius, diameter, count = 0;
    char str[10];
    char color[20];
    printf("Get the num : ");
    scanf_s("%d", &N);

    printf("Enter the mesage\n");
    //for (i = 0; i<N; i++){
        fgets(color, 20, stdin);
    //}
    //for (i = 0; i<N; i++){
        printf("%s", color);
    //}
    return 0;
}

我为VC ++将scanf更改为scanf_s