我正在浏览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字符并逐个获取它们。 任何帮助都是高度关注的。
答案 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”时,这就是正在发生的事情:
'2'
已被阅读c
pn = 0; c = '2';
(来自带有主逻辑的代码段)我们将缓冲区中的值乘以10并添加(0x32 - 0x30
)pn = 2; c = 2;
'3'
读到c
pn
乘以10
给你20
,你添加(0x33 - 0x30
),你得到最后的23。要记住的事情:
getchar()
从stdin printf()
语句可帮助您了解程序流程