2017-06-04 56 views
-2

这是我的代码与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声明,则不会出现此问题。有人可以解释我是什么导致这个问题,以及它如何解决?

+2

'的scanf( “%d%* C”,&N);炭色[N] [20]; ' – BLUEPIXY

+0

让我看看你给出的确切的三个输入 –

+0

问题是你正在使用'scanf'作为用户输入 – melpomene

回答

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

注意,我第一输入字符数组内的数。使用strtoul将其转换为数字(字符串为无符号长整数)。现在在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

'char color [N] [20];':您正在使用未初始化的变量。 – BLUEPIXY

+1

您正在使用'N'而不设置值。你应该防止'scanf(“%[^ \ n]”,color [i]);'''%[^ \ n]“'应该是'%19 [^ \ n]'' – BLUEPIXY

+1

''' – BetaRunner

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

我改变scanfscanf_s为VC++。

+0

你的代码实际上是在做另一件事。 – BetaRunner

+0

确切地说,我的错误 – fardin

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; 
} 
+0

并且在声明'char color [N] [20]'之前,你必须确保'N'具有严格的正值(非零非负) - 当它不是未初始化。 –