getchar()函数是否有自己的缓冲区来存储剩余的输入?

时间:2017-07-21 13:31:00

标签: c kernighan-and-ritchie

我正在浏览K& R的“C编程手册”。 现在函数“getint()”的代码如下: - >

#include<stdio.h>

#define BUFSIZE 100

char buf[BUFSIZE];
int bufp = 0;

int getch(void) {
    return (bufp > 0)?buf[--bufp]:getchar();
}

void ungetch(int c) {
    if(bufp >= BUFSIZE)
        printf("ungetch: too many characters\n");
    else
        buf[bufp++] = c;
}

int getint(int *pn) {
    int c, sign;

    while(isspace(c = getch()));

    if(!isdigit(c) && c != EOF && c != '-' && c != '+') {
        ungetch(c);
        return 0;
    }

    sign = (c == '-')?-1:1;
    if(c == '+' || c == '-')
        c = getch();

    *pn = 0;
    while(isdigit(c)) {
        *pn = (*pn * 10) + (c - '0');
        c = getch();
    }

    *pn *= sign;

    if(c != EOF)
        ungetch(c);


    return c;
}


int main(int argc, char** argv) {

    int r, i;

    while((r = getint(&i)) != EOF)
        if(r != 0)
            printf("res: %d\n", i);

    return 0;
}

现在我没有得到这个功能的一步一步的工作程序,即使我试图在纸上理论上运行它。

当我输入“23”的事实。它是如何转换为23的,我知道将“23”转换为23的逻辑但c = getch()在输入后不会将剩余的“3”存储在缓冲区中,那么它是如何返回3的,转换。 getchar()是否拥有自己的缓冲区,它存储所有的inout字符并逐个获取它们。 任何帮助都是高度关注的。

2 个答案:

答案 0 :(得分:1)

  

当我输入“23”的事实。它是如何转换为23的,我知道将“23”转换为23的逻辑但c = getch()在输入后不会将剩余的“3”存储在缓冲区中,那么它是如何返回3的,转换。 getchar()是否拥有自己的缓冲区,它存储所有的inout字符并逐个获取它们。

据此,我读到你希望getch()以某种方式接收你的整行输入。嗯,那是错的。

首先快速注释getchar() vs getch()这里的混​​淆。在 standard C中,getch()需要类型为FILE *的参数。这是getchar()相当于getch(stdin)。此处显示的代码似乎是标准前的C.我假设getch()的任何出现都应该是getchar()

您需要知道的是stdio.h FILE * 是缓冲的。有不同的模式(无缓冲,线缓冲和完全缓冲)。

stdin是您的默认输入流。它通常来自键盘(但你的程序并不关心它,它可以被重定向来自文件,管道等)。 stdin的默认缓冲模式为行缓冲

因此,当您输入23 <enter>时,2只会进入stdin输入缓冲区以及{{1}只有当一个换行符出现时(按下回车键,这就是字符3),最后可以在\n上阅读。

stdin不关心缓冲。它从getchar()读取,等待有可读的内容。然后它会读取单个字符,因此如果stdin的输入缓冲区中有更多字符,则将保留,直到stdin读取为止或getchar()读取的任何其他功能

答案 1 :(得分:1)

在您提供的代码段中,主要逻辑在此处:

1. *pn = 0;
2. while(isdigit(c)) {
3.     *pn = (*pn * 10) + (c - '0');
4.     c = getch();
5. }

pn是一个缓冲区,它将保存整数的最终值,c是每次getchar()逐个读取的char。所以,当你在阅读“23”时,这就是正在发生的事情:

  1. '2'已被阅读c
  2. 第3行
  3. pn = 0; c = '2';(来自带有主逻辑的代码段)我们将缓冲区中的值乘以10并添加(0x32 - 0x30
  4. pn = 2; c = 2;
  5. '3'读到c
  6. pn乘以10给你20,你添加(0x33 - 0x30),你得到最后的23。
  7. 要记住的事情:

    • getchar()从stdin
    • 逐个读取字符
    • 添加简单printf()语句可帮助您了解程序流程
    • 尝试在gdb下运行它,检查变量值