此代码来自K& R.我已多次阅读,但似乎仍然无法理解。
#define BUFSIZE 100
char buf[BUFSIZE];
int bufp = 0;
int getch(void)
{
return(bufp>0)?buf[--bufp]:getchar();
}
int ungetch(int c)
{
if(bufp>=BUFSIZE)
printf("too many characters");
else buf[bufp++]=c;
}
K& R所说的这两个功能的目的是防止程序读取太多输入。即没有这个代码,一个函数可能无法确定它已经读取了足够的数据而没有先读取太多。但我不明白它是如何运作的。
例如,考虑getch()。 据我所知,这是它需要采取的步骤:
我想问一个更具体的问题,但我真的不知道这段代码是如何实现它的目标的,所以我的问题是:什么是(a)目的和(b)这段代码的推理?
提前致谢。
注意:对于任何K& R风扇,此代码可以在第79页找到(根据您的版本,我想)
答案 0 :(得分:9)
(a)此代码的目的是能够读取一个字符然后“取消读取”它,如果事实证明你不小心读了太多字符(最多100
个字符被“不读”。这在具有前瞻的解析器中很有用。
(b)getch
从buf
读取,如果它有内容,由bufp>0
表示。如果buf
为空,则会调用getchar
。请注意,它使用buf
作为堆栈:它从右到左读取它。
ungetch
在检查堆栈是否已满后,将一个字符推送到堆栈buf
。
答案 1 :(得分:1)
代码并非真正用于“读取太多输入”,而是因为您可以放回已读取的字符。
例如,您使用getch
读取一个字符,查看它是否为字母,将其放回ungetch
并读取循环中的所有字母。这是一种预测下一个角色的方式。
答案 2 :(得分:1)
这段代码旨在供根据他们从流中读取内容做出决策的程序使用。有时这样的程序需要从流中查看一些字符而不实际消耗输入。例如,如果您的输入看起来像abcde12xy789
,则必须将其分为abcde
,12
,xy
,789
(即来自的单独的连续字母组)连续数字的组)你不知道你到达一组字母的末尾,直到你看到一个数字。但是,您不希望在看到它时消耗该数字:您只需知道该组字母即将结束;你需要一种“回放”那个数字的方法。在这种情况下,ungetch
会派上用场:一旦您看到一组字母后面的数字,您可以通过调用ungetch
将数字放回去。您的下一次迭代将通过相同的getch
机制重新选择该数字,从而使您无需保留您阅读但未消费的角色。
答案 3 :(得分:0)
这是通过上面的代码片段解决的。这个概念的扩展用于文件处理,尤其是编辑文件。在这种情况下,不是使用getchar()来获取标准输入的输入,文件是用作输入的来源。
答案 4 :(得分:0)
我对给出的代码有疑问。在此代码中使用缓冲区(以堆栈的形式)是不正确的,因为当获得多个额外的输入并压入堆栈时,在后续处理(从缓冲区获取输入)中会产生不良影响。
这是因为在进行后续处理(获取输入)时,此缓冲区(堆栈)将以相反的顺序提供额外的输入(意味着最后给出的最后一个额外输入)。
由于堆栈具有LIFO(后进先出)属性,因此必须对此代码中的缓冲区进行排队,因为在有多个额外输入的情况下,缓冲区会更好地工作。
此代码错误使我感到困惑,最后必须对缓冲区进行如下所示的操作。
#define BUFSIZE 100
char buf[BUFSIZE];
int bufr = 0;
int buff = 0;
int getch(void)
{
if (bufr ==BUFSIZE)
bufr=0;
return(bufr>=0)?buf[bufr++]:getchar();
}
int ungetch(int c)
{
if(buff>=BUFSIZE && bufr == 0)
printf("too many characters");
else if(buff ==BUFSIZE)
buff=0;
if(buff<=BUFSIZE)
buf[buff++]=c;
}