【问题标题】:getchar() and conditioning a loop to break with a specific chargetchar() 并调节循环以中断特定字符
【发布时间】:2017-03-14 10:04:10
【问题描述】:

我正在编写臭名昭著的《Prentice Hall 软件系列》一书,并尝试他们编写的代码并对其进行修改以了解有关 C 的更多信息。

我正在控制台中的 Fedora 25 上使用 VIM。以下代码是书中的引用,我知道缺少“int”以及 argc 和 argv 等。

Kernighan 和 Ritchie - C 编程语言:第 20 页

#include <stdio.h>
/* copy input to output; 1st version  */   
main(){       
    int c;
    c = getchar();       
    while (c != EOF) {           
        putchar(c);           
        c = getchar();       
    }   
}

使用此代码,我无法让“EOF”工作。我不确定“ctr + z”是否真的是真正要做的事情,因为它会退出控制台中的任何控制台程序。

好吧,因为我不确定我将条件更改为

...
while (c != 'a') {
...

所以通常如果我输入“a”,while 条件应该会中断并且程序应该终止。好吧,当我尝试运行它并输入'a'时它不会。这里有什么问题?

谢谢你们!

【问题讨论】:

  • 了解 C 的第一件事:int main.
  • 我知道它实际上是“int main(int argc, char *argv[]) 我引用了这本书,它是这样写的,所以请与我裸露。
  • 买一本更好的书。最好是第一次学得好,以后再忘掉。
  • @n.m.先生,吹毛求疵,int main(void).. :)
  • 自从 K&R 写了他们的书以来,C 发生了很大的变化。甚至他们关于 ANSI C 的书也包含代码示例,这些代码示例会在符合当前 C 标准修订版的现代编译器中中断。

标签: c getchar kernighan-and-ritchie fedora-25


【解决方案1】:

代码没有问题(main 的陈旧声明除外)。

通常,在 Unix 上,文件的结尾由 ctrl-D 向程序发出信号。如果您直接按 ctrl-D 或在按换行符后按,您的程序将显示为 EOF

然而,上面的简短解释隐藏了很多微妙之处。

在 Unix 中,终端输入可以以两种模式之一运行(称为 IIRC 生和熟)。在熟模式(默认)下,操作系统将缓冲来自终端的输入,直到它读取新行或 ctrl-D 字符。然后它将缓冲的输入发送到您的程序。

最终,您的程序将使用read 系统调用来读取输入。 read 将返回读取的字符数,但通常会阻塞,直到它有一些字符要读取。 getchar 然后将它们一一传递给它的调用者。所以getchar 将阻塞直到接收到整行文本,然后再处理该行中的任何字符。 (这就是为什么当你使用a时它仍然不起作用的原因)。

按照惯例,read 系统调用在到达文件结尾时返回 0。这就是getchar 知道将EOF 返回给调用者的方式。 ctrl-D 具有强制read 读取和清空缓冲区的效果(如果它在新行之后立即发送),这使得它看起来像getchar 一样它已达到 EOF,即使没有人关闭输入流。这就是为什么 ctrl-D 在换行后直接按下时起作用,但在输入某些字符后按下时不起作用的原因。

【讨论】:

  • 感谢您提供了非常有见地的解释,现在这完全有道理!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-08-28
  • 2015-06-04
  • 2017-07-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-01
相关资源
最近更新 更多