【问题标题】:C programming — loopC 编程——循环
【发布时间】:2018-03-10 06:01:11
【问题描述】:

我正在学习 C 语言书中的练习。我在他介绍循环的第一章。在这段代码中:

#include <stdio.h>

/* copy input to output; 1st version */

int main() {
  int c, n1;

  n1 = 0;
  while ((c = getchar()) != EOF) {
    if (c == '\n') {
      ++n1;
    }
    printf("%d\n", n1);
  }
}

在这里我计算行数。当我只是按 Enter 而不输入任何其他内容时,我得到了正确的行数,但是当我输入一个字符然后按 Enter 键时,循环运行两次,而第二次不要求输入。我得到两个输出。 这是输出的样子:

   // I only hit enter
1
   // I only hit enter
2
   // I only hit enter
3
g // I put char 'g' then hit enter
3
4

3 和 4 同时打印。为什么在循环已经迭代之后打印 4 ?我以为循环会重新启动并在打印 4 之前询问我的输入。

【问题讨论】:

  • 请注意,计数器仅在换行符处递增,但收集的每个字符都是循环迭代
  • 循环在接收到输入时打印 n1 并在输入为换行时将 1 添加到 n1。它为 g 打印 n1,然后向其添加 1 并为换行打印 n1。
  • 除非你真的应该为每个字符在一行上打印一个数字(在一行上写一篇文章,然后看着数字在屏幕上滚动),否则printf() 不恰当地放在里面循环而不是在它之后。如果您指的是 K&R (Kernighan & Ritchie) “The C Programming Language”,那么您已经抄错了代码。

标签: c while-loop


【解决方案1】:

getchar 函数一次读取一个字符。将打印getchar 读取的输入中每个字符的行数,无论该字符是否为换行符,但仅当输入中有换行符时计数器才会增加。

当您输入g 时,进入标准输入的实际输入为g\ngetchar 将在两次迭代中读取此输入,这就是它两次打印行数的原因。

如果您将 print 语句放在 if 块中,那么它将仅打印换行符。如果将 print 语句放在循环之外,那么它只会在输入的末尾打印行数。

【讨论】:

  • 所以 getchar() 在 if 语句的主体中以两次迭代读取输入?那么除了while循环之外,代码中还有另一个迭代或循环吗?
【解决方案2】:

要明确这是您正在处理的终端。

默认情况下,终端不会得到来自用户\n的输入。然后整行放在stdin中。

现在正如我之前所说的,程序不受stdin 的缓冲影响。然后将字符作为输入,并按照您的预期进行处理。唯一的障碍是终端缓冲 - 线路缓冲。

从标准这里您将看到getchar 的行为方式:-

getchar 函数从stdin 指向的输入流中返回下一个字符。如果流位于文件结尾,则设置流的文件结尾指示符,getchar 返回EOF。如果发生读取错误,则设置流的错误指示符并 getchar 返回 EOF。

现在这些字符是什么 - 这些字符包括 \n - \n 是您在终端中输入的内容,然后通过按 ENTER 输入到 stdin。在这里,您之前输入了\n 的字符。这次您输入了两个字符。这就是你看到的行为的原因。

【讨论】:

  • 你能给我举个例子吗?你说的一半都超出了我的想象。比如什么是终端缓冲?
  • @TheCaptain.: 事情是这样的——如果你输入任何字符,除非你在字符后按回车,否则 getchar 不会考虑它。这是在终端缓冲。
猜你喜欢
  • 2015-06-22
  • 2019-02-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-17
  • 2022-11-19
  • 1970-01-01
相关资源
最近更新 更多