代码只有2个输入,虽然它有3个fgets

时间:2017-07-11 10:30:14

标签: c arrays scanf fgets

#include<string.h>
#include<stdio.h>
#include<stdlib.h>

int main(){
    int num;
    scanf("%d",&num);  // The input is 3 so i use it to simplify the question 
    char array[num][1000];
    fgets(array[0],1000,stdin);
    fgets(array[1],1000,stdin);
    fgets(array[2],1000,stdin);
    printf("%s %s %s",array[0],array[1],array[2]);
}

第一个输入,即对于scanf是3然后我输入mahatma和gandhi。现在它应该要求最后一个fgets的另一个输入,但程序结束打印mahatma gandhi。但是我不使用scanf然后结果是正确的。如果可能请提供代码。 P.S-我第一次使用fgets,所以可能存在一个非常基本的错误。

3 个答案:

答案 0 :(得分:2)

正如xing在评论中指出的那样,原因是scanf()在流中留下了一个换行符(由文件句柄stdin表示),该换行符将在{{1}的第一次调用时读取},导致它立即返回。

一般的解决方案不是在同一输入流上混合格式化输入(如fgets())和面向行的输入(如scanf()),因为它们会以意想不到的方式进行交互。这里的示例(fgets()留下要读取的换行符,并且由于遇到换行符而立即返回scanf())是在同一个流上混合输入样式的许多可能后果之一。

一种方法是使用fgets()将数据读取到字符串,然后使用fgets()从该字符串中读取int。与sscanf()的互动仅使用stdin

另一种选择是将fgets()的所有用法更改为使用fgets()。这将需要找到一种合理的格式(请记住,scanf()在遇到空格时会停止读取内容 - 尽管有一些格式说明符可以改变这种格式。)

scanf()格式字符串添加空格的建议存在缺陷。它适用于特定情况(如此情况),但不适用于其他情况。例如,如果您执行表单循环

scanf()

由于循环中// assume variables declared as in the OP's question while (some_condition_that_is_true_more_than_once()) { scanf("%d ",&num); fgets(array[0],1000,stdin); fgets(array[1],1000,stdin); fgets(array[2],1000,stdin); } 的最后一次调用与下一次迭代中的fgets()调用的交互,仍会存在潜在的交互(取决于用户输入的内容),从而产生意外结果

答案 1 :(得分:1)

考虑对所有输入使用fgets。根据需要使用sscanf或其他人解析 检查fgets和sscanf的返回,因为这将表明存在问题 do / while循环将继续,直到处理正整数为止 包括提示以澄清预期的输入。

#include <string.h>
#include <stdio.h>
#include <stdlib.h>

int main(){
    char input[50] = "";
    int num = 0;
    int loop = 0;
    int valid = 0;

    do {
        printf ( "enter an integer\n");
        if ( fgets ( input, sizeof input, stdin)) {
            if ( 1 != ( valid = sscanf ( input, "%d", &num))) {// 1 means successful scan on an integer
                valid = 0;
                printf ( "try again to enter an integer\n");
            }
        }
        else {// fgets could not get input
            fprintf ( stderr, "problem with input\n");
            return 0;
        }
    } while ( !valid || num < 0);

    char array[num][1000];

    for ( loop = 0; loop < num; loop++) {
        printf ( "enter text for array[%d]\n", loop);
        if ( fgets(array[loop],sizeof array[loop], stdin)) {
            array[loop][strcspn( array[loop], "\n")] = '\0';// remove trailing newline if any
        }
        else {
            fprintf ( stderr, "problem with input\n");
            return 0;
        }
    }

    for ( loop = 0; loop < num; loop++) {
        printf("%s ", array[loop]);
    }
    printf("\n");
}

答案 2 :(得分:0)

只需在scanf()中提供这样的空格

scanf("%d ",&num);

这将使调用fgets三次(正如Peter所指出的那样)。发生这种情况的原因是,当您在scanf()缓冲区STDIN\n后存储并进入第一个fgets()调用时按ENTER键。