了解K& R的getint()(第5章:指针和数组,练习1)?

时间:2018-05-18 15:47:58

标签: c input

我是一名通过K& R自学C的新手程序员。我不理解它们的函数getint()的设计,它将一串数字转换为它所代表的整数。我会问我的问题,然后发布下面的代码。

如果getch()返回的非数字字符不是' - '或' +',它使用ungetch()将此非数字字符推回到输入上,并返回0.因此,如果再次调用getint(),则getch()将返回相同的非-digit字符被推回,所以ungetch()会再次将它推回去等等。我理解它的方式(这可能是错误的),如果函数传递了任何非数字字符,该函数会完全中断。 / p>

练习并没有解决这个问题。它要求确定一个' - '或' +'后跟非数字是0的有效表示。

我到底错过了什么?如果输入不是0-9,他们是否设计了getint()来进行无限循环?为什么?

这里是他们的主要调用getint()的getint()[edit]的代码:

int getint(int *);

int main()
{
        int n, array[BUFSIZE];
        for (n = 0; n < BUFSIZE && getint(&array[n]) != EOF; n++)
                     ;
        return 0;
}

 int getch(void);
 void ungetch(int);

int getint(int *pn)
{
        int c, sign;
        while (isspace(c = getch())
                ;
        if (!isdigit(c) && c != EOF && c != '+' && c != '-') {
                ungetch(c); //this is what i don't understand
                return 0;
        }

        sign = (c == '-') ? -1 : 1;

        if (c == '-' || c == '+')
                c = getch();
        for (*pn = 0; isdigit(c); c = getch())
                *pn = 10 * *pn + (c - '0');
        *pn *= sign;
        if (c != EOF)
                 ungetch(c);
        return c;
}

int buf[BUFSIZE];
int bufp = 0;

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

void ungetch(int c)
{
        if (bufp >= BUFSIZE)
                printf("ungetch: can't push character\n");
        else
                buf[bufp++] = c;
}

2 个答案:

答案 0 :(得分:1)

正如当前所写,getint()函数正在尝试从用户输入中读取一个整数并将其放入*pn

  1. 如果用户输入正数或负数(带符号或没有符号),* pn会更新为该数字,而getint()会返回一些正数(数字后面的下一个字符)。

  2. 如果用户输入无效号码,则*pn不会更新,getint()会返回0(表示失败)。

      

    如果函数传递了任何非数字字符,该函数将完全中断。

    那是对的。对getint()的所有后续调用都将失败,因为最后一个字符已传递给ungetch()。你理解的是正确的。

    但这就是getint()应该如何处理垃圾输入。它只是拒绝它并返回0(意味着它失败了)。 getint()负责处理非整数输入并为下次读取准备新输入。这不是一个错误。

    唯一的错误是&#39; - &#39;或&#39; +&#39;之后是非数字,目前被视为0的有效表示。这是作为练习留给读者的。

  3. 如果用户输入EOF*pn未更新(乘以1),getint()则返回EOF

答案 1 :(得分:0)

推理与scanf类似,不会消耗与转化说明符不匹配的字符 - 您不想消费不属于有效整数的字符,但是可能是有效字符串或其他类型输入的一部分。 getint无法知道它拒绝的输入是否是其他有效的非数字输入的一部分,因此它必须保持输入流与发现它的方式相同。