【问题标题】:Understanding K&R's getint() (Chapter 5: Pointers & Arrays, Exercise 1)?了解 K&R 的 getint()(第 5 章:指针和数组,练习 1)?
【发布时间】:2018-05-18 15:47:58
【问题描述】:

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

如果 getch() 返回一个不是“-”或“+”的非数字字符,它会使用 ungetch() 将该非数字字符推回输入,并返回 0。因此,如果 getint()再次调用时, getch() 只会返回被推回的同一个非数字字符,因此 ungetch() 会再次将其推回,依此类推。按照我理解的方式(可能是错误的),如果函数完全中断,则它传递了任何非数字字符。

练习没有让你解决这个问题。它要求修正一个事实,即“-”或“+”后跟一个非数字是 0 的有效表示。

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

这是他们的 getint() [编辑] 代码,主要调用 getint():

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;
}

【问题讨论】:

  • 调用getint的代码在哪里?
  • 刚刚添加了 main() 以使用 getint() 填充数组。谢谢
  • 我认为如果您想使用 getch 来获得数字和非数字输入的混合。如果您有一堆非数字输入,重复调用 getint 会在没有 ungetch 的情况下一次吞噬一个字符。
  • 我还是不太明白。添加 ungetch() 不意味着 getint() 永远不会超过第一个非数字字符吗?
  • 这是一个错误情况。但该函数并非旨在返回错误指示。这是一个非常糟糕的做法,你不会在真正的程序中考虑。避免用太多细节压倒读者肯定是目标。以防万一,当你的数组被零填充时,你就会知道发生了什么:)

标签: c input


【解决方案1】:

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

  1. 如果用户输入正数或负数(带符号或不带符号),*pn 将更新为该数字,getint() 返回某个正数(数字后的下一个字符)。

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

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

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

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

    唯一的错误是“-”或“+”后跟一个非数字当前被认为是 0 的有效表示。这留给读者作为练习。

  3. 如果用户输入EOF*pn 不会更新(乘以 1)并且getint() 返回EOF

【讨论】:

    【解决方案2】:

    推理类似于scanf 不使用与转换说明符不匹配的字符 - 您不想使用不属于有效整数的内容,但可能是有效字符串或其他类型输入的一部分。 getint 无法知道它拒绝的输入是否是其他有效的非数字输入的一部分,因此它必须以与找到它相同的方式离开输入流。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-25
      • 2016-12-28
      相关资源
      最近更新 更多