【问题标题】:Why aren't my characters being counted when I enter input via the command line? [duplicate]为什么当我通过命令行输入时我的字符不被计算在内? [复制]
【发布时间】:2015-08-29 02:11:24
【问题描述】:

当我使用这段代码时,我可以在命令行中输入并取回我输入的内容:

main() {
  int c;
  while ((c = getchar()) != EOF) {
    putchar(c);
  }
}

输出:

~/code/c $ ./a.out
one
one
two
two

但是当我使用这段代码时,它只在我输入数据时有效,而不是当我在命令行中输入数据时:

main() {
  int nc;
  nc = 0;
  while (getchar() != EOF) {
    nc++;
  }
  printf("%d\n", nc);
}

当我从文本文件中输入数据时:

~/code/c $ ./a.out < practice.txt
14

当我尝试从命令行输入数据时:

~/code/c $ ./a.out
one
two
three

发生了什么事?

【问题讨论】:

  • 你没有告诉程序没有更多的数据(发送给它 EOF),所以它正在等待更多的输入。您不会打印每行的长度;仅适用于整个文件。由于您可能在类似 Unix 的机器上,您可能应该在一行的开头键入 Control-D 以查看最终答案。如果您在该行的中途键入 Control-D,则需要键入第二个 Control-D 以指示 EOF。
  • 为什么我的第一个代码示例的行为方式如此?我希望在每次按键后,它会打印字符。发生的事情是它在按下enter 后吐回我按下的字符。这是为什么呢?
  • 在您输入换行符(或 Control-D)之前,终端驱动程序不会将字符发送到程序。这允许您编辑行(退格等)。因此,除非您更改终端设置,否则您的程序每次点击返回时都会获取一行数据。因此观察到的行为。

标签: c


【解决方案1】:

while 循环永远不会退出,因为while (getchar() != EOF) 始终为真。完成输入后,在 Linux 上按 Cntrl+D 或在 Windows 上按 Ctrl+Z 以指示 EOF。

【讨论】:

  • Linux 上的 Control-C 将(通常)中断程序,因此不会产生答案。您通常应该在一行的开头键入 Control-D 以指示 EOF。 (“通常”在那里,因为键是可配置的。)
  • @JonathanLeffler 是的,你是对的,我只是想错了
  • 我在 Mac OSX 上。知道为什么我必须按两次Ctrl+D 吗?按a+b+c+CtrlD 后,我得到这个:abc^D。当我再次按CtrlD 时,我得到了这个:abc3D
  • @AdamZerner 我不完全确定,因为我以前从未在 Mac OSX 中编程,甚至几乎没有使用过它。但是,如果您键入a b c 按回车键然后按 Ctrl+d 并再次回车会发生什么?这行得通吗?还是您仍然需要按两次 Ctrl+d?
  • 这行得通,虽然它给了我像4D 这样的输出(我正在寻找的输出只是4)。似乎来自^DD 仍然存在。
【解决方案2】:

就像每个人都提到的那样,您的程序不会停止。 while 循环需要一个条件才能停止。您必须使用 CTRL+Z (Win) 或 CTRL+D(Unix) 来停止它,当您使用管道时,它实际上会为您发送该字符。因为EOFEND_OF_FILE。因此,当您到达文件末尾时。操作系统会为您发送该字符。

【讨论】:

  • 挑选尼特:Control-Z 或 Control-D 是 EOF 的指示器;字符不会被发送到程序。当你管道数据时,当所有数据都被读取并且没有进程仍然可以写入管道时,会指示EOF;同样,没有发送任何字符来指示 EOF。在这两种情况下,read() 系统调用(或其许多亲属之一)都返回 0,表示没有更多数据。请参阅Why is EOF recognized only if it is the first character on the line 和其他相关问题。
  • 是的。 EOF 实际上是一个条件。同时,在 C 标准库中,getchar 等字符读取函数返回一个等于符号值(宏)EOF 的值,表示出现了文件结束条件。 EOF 的实际值取决于系统(但通常为 -1,例如在 glibc 中)并且不等于任何有效的字符代码。块读取函数返回读取的字节数,如果小于请求的字节数,则到达文件末尾。 -维基
  • 严格地说,“如果这比要求的少”,这意味着目前只有给定的数据可用。例如,如果一个程序从终端请求 1 KiB 数据,但您只输入 Hi,那么将读取 3 个字节(Hi 和换行符),但这并不表示 EOF .当返回值为读取的零字节时指示 EOF。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-07-31
  • 1970-01-01
  • 2017-06-30
  • 1970-01-01
  • 2020-02-26
  • 2011-01-08
  • 1970-01-01
相关资源
最近更新 更多