C语言中,在使用scanf()函数后,printf()函数没有输出,直到下一个scanf()函数出现。

3

我正在尝试读取输入的每行第一个字符,然后根据第一个字符确定其余部分的格式。接着,根据所接收到的命令使用scanf()函数读取值。

char name[50];
int rating, ref;

int main() {
    int command;
    while (command = getchar()) {
        if (command == EOF || command == '\0') break;
        if (!processCommand(command)) break;
        printf("done processing, waiting for new command\n");
    }
}

char processCommand(int command) {
    switch (command) {
        case 'a':
            printf("starting\n");
            if (scanf(" %s %d %d\n", name, &rating, &ref) != 3) return 0;
            // SOME PROCESSING
            printf("done\n");
            break;
        default:
            exit(EXIT_FAILURE);
    }
    return 1;
}

问题在于输出结果看起来像这样:
./program.out
a Test 5 12345
starting
a Testing 0 23456
done
done processing, waiting for new command
starting

基本上,printf不会被刷新到标准输出流直到下一个processCommand()被调用。我已经尝试了以下所有方法:

fflush(stdin);
while ( getchar() != '\n' );
fflush(stdout);
setbuf(stdout, NULL);
setvbuf(stdout, NULL, _IONBF, 0);

它们都不会改变输出结果。我在这里做错了什么吗?


1
“command” 应该是一个 int,因为 getchar() 返回的是一个 int - pzaenger
@pzaenger 感谢您告诉我。我已经更新了代码。不幸的是,它并没有影响输出。 - Xeos
1
scanf(" %s %d %d\n"... 这段代码有点可疑。最后的 "\n" 可能会读入比预期更多的内容。 - chux - Reinstate Monica
getchar()scanf()不太兼容。最好只使用scanf(),因为无论如何,您的键盘输入都是行缓冲的。此外,请阅读scanf()的手册页面。您不需要在其中使用\n - r3mainer
@chux修复了它。你能把它添加为答案吗? - Xeos
@squeamishossifrage 问题在于输入格式根据行首字母不同而不同。因此,对于以'b'开头的行,我可能需要使用" %d",而对于以'c'开头的行,则需要使用" %s %d",我无法在一个scanf()中完成所有操作。最终发现\n才是问题的原因。 - Xeos
1个回答

6

if (scanf(" %s %d %d\n" 中的 "\n" 防止 scanf() 在第二个 int 后,直到输入非空格字符才返回。

"\n" 并不仅仅是扫描 '\n',而是扫描所有的空白字符,直到出现另一个非空白字符。这通常涉及到用户输入的缓冲区中有第二行文本。

" %s %d %d\n" 的末尾去掉 '\n'

更好的方法是使用 fgets() 读取数据,放弃使用 scanf()。使用 sscanf()strtok()strtod() 等函数来代替。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接