c - 不清楚 stdin 输入问题

标签 c buffer stdout stdin

我写了一段代码来帮助自己理解涉及 stdinstdout 时事情是如何工作的。

这是我的代码:

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

void prompt(){
    int i=0;
    printf("please select:\n");                  //string1
    printf("1.input\n2.print\n3.Exit\n");        //string2
    scanf("%d",&i);
    switch(i){
        case 1:
            printf("Data input!\n");
            break;
        case 2:
            printf("data printed!\n");
            break;
        case 3:
            exit(0);
        case 10:
            printf("Newline detected!");                      //string3
        default:
            printf("Please input a valid number!(1-3)");    //string4
    }
}   

int main()
{
    while(1)
        prompt();

    return 0;
}

我希望这段代码做的是:

  1. 提示我输入;
  2. 然后我输入一个数字 4,它不在大小写中;
  3. 因此将匹配默认大小写并打印字符串 'Please input a valid...'(字符串 4)。
  4. 因为stdin缓冲区中还有一个换行符,在下一个循环中, 变量'i'会自动得到一个换行符,在ACSII中是10
  5. 所以在打印出'please select..1.input\n2.print....'之后,会立即打印出一个字符串'Newline detected!'(string 3)。
  6. 然后代码进入第三个循环,提示我输入....

但那永远不会发生。我在输出中看不到任何“检测到换行符!”,即使我输入了数字 4,这不在大小写范围内。

任何人都可以详细说明这段代码的具体工作原理吗?

顺便说一句:我最初假设当标准输出中打印了一些东西时,标准输入缓冲区将被自动刷新。但一些事实证明我错了。我的假设是对还是错?

此外,当我输入一个字符(例如 g)而不是数字时,我在屏幕上打印了 string 1, string 2, sring 4无限地。这是为什么?

################################################## #####################3

编辑:查看答案后,我制作了另一个片段,以帮助理解。

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

void output();

int main()
{
    int i;
    printf("Enter a number here:\n");
    scanf("%d",&i);

    output();

    return 0;
}

void output(){
    char a;
    if (scanf("%c",&a)!=1){
        printf("scanf error!!");
        exit(1);
    }
    switch(a){
        case 'a':
            printf("an char a is entered");
            break;
        case 'b':
            printf("an char b is entered");
            break;
        default:
            printf("%c",a);
            printf("other thing is entered");
    }
}

无论您在第一次程序提示时输入什么,您都不会得到第二次提示。例如,当程序第一次提示您时,如果您输入数字 4,那么您将得到一个换行符和一个字符串“other thing is entered”打印在您的屏幕上。这是为什么?

最佳答案

as there is still a newline character left in the stdin buffer, in the next loop, the variable 'i' will automatically get a newline character, which is 10 in ACSII

So after printing out 'please select..1.input\n2.print....',, a string 'Newline detected!'(string 3) will be immediately printed out.

这是不正确的。当你使用

scanf("%d",&i);

所有空格都被忽略,包括换行符。

And then the code goes into the third loop, and prompt me for input....

现在您知道它停留在第二个循环中,等待输入数字。

I originally assume that when there is something printed in the stdout, the stdin buffer will be flushed automatically. But some fact proved me wrong. Is my assumption true or false?

这个假设是错误的。当您等待来自 stdin 的输入时,stdout 被刷新。

Also, when I enter a character(for example, a g) rather than a number, I got string 1, string 2, sring 4 printed in the screen infinitly. Why is that?

那是因为程序在执行该行时无法读取字符:

scanf("%d",&i);

字符留在输入流中。您没有任何代码可以从输入流中删除该字符。这使得程序处于无限循环中。

关于c - 不清楚 stdin 输入问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30950218/

相关文章:

c - MacBook Pro 上的 C 程序终端权限被拒绝

c - 扩展字符串而不连接

c++ - 为什么大型本地数组会使我的程序崩溃,而全局数组却不会?

windows - 检查 Windows 文件是否重定向到自身

c - 第一次 dlopen 后共享库函数可以正常工作

c - fread 缓冲区大小 - 我有大量内存,为什么不把它设置得很大呢?

audio - 快速傅里叶变换 FFT 中的幅度值因恒定输入信号而异?

javascript - Web 音频 API 不连续播放声音

c - 在 bash 中重定向 stdout 与在 c 中使用 fprintf 写入文件(速度)

java - 在 Windows : Get unbuffered stdout from C program into Java program InputStream [Now with minimal example! ]