ungetc(或从K& R取消)的目的是什么?

时间:2009-01-24 20:30:20

标签: c kernighan-and-ritchie kr-c

任何人都可以向我解释ungetch的目的吗? 这是来自K& R第4章,您可以在其中创建反向波兰计算器。

我在没有调用ungetch的情况下运行程序,在我的测试中它仍然可以正常工作。

 int getch(void) /* get a (possibly pushed back) character */
    {
        if (bufp > 0)
        {
            return buf[--bufp];
        }
        else
        {
            return getchar();
        }
    }

    void ungetch(int c) /* push character back on input */
    {
        if (bufp >= BUFSIZE)
        {
            printf("ungetch: too many characters\n");
        }
        else
        {
            buf[bufp++] = c;
        }

}

(我已经删除了getch中的三元运算符以使其更清晰。)

4 个答案:

答案 0 :(得分:27)

我不知道你所指的具体例子(自从我读K& R以来已有23年,这是第一版。),但通常在解析它时很方便'偷看'下一个字符,看它是否是您当前正在解析的内容的一部分。例如,如果您正在读取一个数字,您希望继续读数字,直到您达到非数字。 Ungetc允许数字阅读器查看下一个字符而不消耗它,以便其他人可以阅读它。在Greg Hewgill的“2 3+”的例子中,数字阅读器将读取3位数字,然后读取加号并知道数字已完成,然后取消加号,以便稍后阅读。

答案 1 :(得分:10)

尝试运行程序,运算符周围没有空格。我不记得该示例的格式,我没有K& R方便,但不使用“2 3 +”尝试“2 3+”。解析数字时可能会使用ungetch(),因为数字解析器将读取数字,直到获得非数字的数字。如果非数字是空格,那么下一个getch()将会读取+并且一切都很好。但是,如果下一个非数字是+,则需要将其推回输入流,以便主读取循环可以再次找到它。

希望我能正确记住这个例子。

答案 2 :(得分:4)

它经常用于词汇扫描程序(编译器中将文本分成变量名,常量,运算符等块的部分)。扫描仪的功能不是必要,它非常方便。

例如,在读取变量名时,在读取不能成为变量名的一部分的字符之前,您不知道何时完成。但是你必须记住那个角色并找到一种方法将它传达给词法分析器的下一个块。你可以创建一个全局变量或其他东西,或者将它传递给调用者 - 但是你如何返回其他东西,比如错误代码?相反,你ungetch()将字符放回到输入流中,用你的变量名做任何你想做的事情并返回。然后当词法分析器开始读取下一个块时,它不必四处寻找额外的字符。

答案 3 :(得分:-2)

看看这段代码,你会理解:

#include <conio.h>
#include <stdio.h>
int main()
{
    int y=0;
    char t[10];
    int u=0;
    ungetch('a');
    t[y++]=getch();
    ungetch('m');
    t[y++]=getch();
    ungetch('a');
    t[y++]=getch();
    ungetch('z');
    t[y++]=getch();
    ungetch('z');
    t[y++]=getch();
    ungetch('a');
    t[y++]=getch();
    ungetch('l');
    t[y++]=getch();
    ungetch('\0');
    t[y++]=getch();
    ungetch('\0');
    t[y++]=getch();
    ungetch('\0');
    t[y++]=getch();
    printf("%s",t);
    return 0;
}