【问题标题】:getchar buffered input, EOF and terminal drivergetchar 缓冲输入、EOF 和终端驱动程序
【发布时间】:2014-06-15 05:56:21
【问题描述】:

我试图了解终端驱动程序如何与 getchar 一起工作。以下是我在阅读 KandR 时编写的一些示例代码:

代码 1:

#include <stdio.h>

int main(){

  int c = getchar();
  putchar(c);


  return 0;

}

代码 2:

    #include <stdio.h>

    int main(){

    int c = EOF;

    while((c=getchar()) != EOF){
    printf("%c",c);
    }
    return 0;
}

代码 3: //模拟 wc 命令功能的准系统程序

    #include <stdio.h>
    #define IN 1
    #define OUT 0

    int main(){
      //nc= number of characters, ns = number of spaces, bl=number of newlines, nw=number of words
      int c = EOF,nc=0,nw=0,ns=0,nl=0, state = OUT;

      while((c=getchar())!=EOF){
        ++nc;
        if(c=='\n'){
          ++nl;
          state = OUT;
        }
        else if(c==' '){
          ++ns;
          state = OUT;
        }

        else{
          if(state == OUT){
          state = IN;
          ++nw;}
        }

      }

      printf("\n%d %d %d %d",nc,nw,ns,nl); 
return 0;
}

我想了解终端驱动程序何时将输入字符串真正移交给程序。假设我的输入是字符串“这是一个测试”并且我按下回车键,那么上面提到的代码是这样工作的:

代码1:输出“t”(程序结束)

代码2:输出“这是一个测试”,跳到下一行(因为它也输出了我按下的回车)并再次等待输入。

代码 3:不输出上述字符串后跟回车的任何内容。我需要按 Ctrl+D 才能显示输出(输出为 15 4 3 1)

1) 为什么在代码 3 的情况下我需要显式按 Ctrl+D (EOF) 才能将输入发送到我的程序?换句话说,为什么我的输入字符串在我按下回车后在代码 1 和代码 2 的情况下被发送到我的程序?为什么它也不要求EOF?

2) 另外,在代码 3 的情况下,如果我在输入字符串后不按 enter,我需要按 Ctrl+D 两次才能显示输出。为什么会这样?

编辑:

对于另一个输入说“TESTING^D”,上面的代码是这样工作的:

1) 输出“T”并结束

2) 输出“TESTING”并等待更多输入

3) 在按下另一个 Ctrl+D 之前不输出任何内容。然后输出 7 1 0 0。

在这种输入的情况下,终端驱动程序在代码 1 和代码 2 的情况下收到 Ctrl+D 时将输入字符串发送给程序。这是否意味着 /n 和 Ctrl+D 的处理方式相同,即它们两者都充当终端驱动程序将输入发送到程序的标记?那么为什么我需要在第二种情况下按两次 Ctrl+D 呢?

http://en.wikipedia.org/wiki/End-of-file 表示驱动程序在换行时将 Ctrl+D 转换为 EOF。但是在我的“TESTING^D”输入的情况下,即使 ^D 与输入的其余部分在同一行上,它也可以正常工作。对此有什么可能的解释?

【问题讨论】:

  • 解决您的最后一个问题:链接的 Wikipedia 文章没有引用来源。据我记得,ctrl+d 如果终端缓冲区被刷新,则发送EOF,否则,它会刷新缓冲区。换行符也会刷新缓冲区。不幸的是,我目前也找不到这方面的参考。 HTH
  • @mafso 感谢您的信息。

标签: c getchar putchar


【解决方案1】:

一般信息:

如果代码2:您还需要执行ctrl+D才能退出。

实际上 EOF 是通过按 ctrl+D 来实现的,所以你的 while 循环条件是这样说的:

  1. 从键盘获取输入
  2. 将其存储在 c 中
  3. 如果输入不等于 EOF,则执行 while 循环体

EOF 就是整数 -1,这可以在终端中通过按 ctrl+D 来实现。所以举个例子:

while((c=getchar()) != EOF){
   // execute code
}

printf("loop has exited because you press ctrl+D");

条件继续接受输入,但当您按 ctrl+D 时停止,然后继续执行其余代码。

回答您的问题:

1) 为什么在代码 3 的情况下我需要显式按 Ctrl+D (EOF) 将输入发送到我的程序?换句话说, 为什么在代码 1 和代码的情况下我的输入字符串被发送到我的程序 2 按回车后?为什么它也不要求EOF?

在代码 2 和 3(不仅仅是 3)中,您需要按 Ctrl+D,因为 while 循环仅在读取 EOF 时才停止从键盘获取输入。在代码 1 中您没有循环,因此当您输入一个或多个字符时,程序将读取输入的字符但仅存储第一个字符,然后打印并终止程序,因此在这种情况下不需要 EOF因为你不会在任何情况下要求它。

2) 另外,在代码 3 的情况下,如果我在输入后不按 Enter 字符串,我需要按两次 Ctrl+D 才能显示输出。 为什么会这样?

如果您在程序需要输入时开始输入,然后在输入至少一个字符后按 ctrl+D,这将告诉程序停止输入并返回输入的字符。之后,如果你在之前没有输入任何字符的情况下再次按 ctrl+D,这将返回 EOF,这将不满足 while 循环的条件并跳过继续执行其余代码

【讨论】:

  • 所以如果我理解正确,/n 和 Ctrl+D 的处理方式相同,即它们都用作终端驱动程序将输入发送到程序的标记?只有当 Ctrl+D 单独发送而没有任何文本时,它才会将其视为 EOF?在代码 1 和 2 中:当我在输入后按 /n 或 Ctrl+D 时,输入可用于 putchar?
  • ctrl+D 与输入信号程序处理输入。 Enter 附加 \n 字符并将输入发送到程序。但请注意,在没有输入之前 ctrl+D 将返回 EOF @Karan
  • Block-reading functions return the number of bytes read, and if this is fewer than asked for, then the end of file was reached. en.wikipedia.org/wiki/End-of-file @Karan
  • 点赞!维基百科链接说 Ctrl+D 应该是驱动程序将其转换为 EOF 的行的开头。但是当我在代码 3 中输入“TESTING^D^D”时,我的程序会给出输出并退出,即使第二个 ^D 与输入在同一行。我在这里错过了什么?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-05-23
  • 1970-01-01
  • 1970-01-01
  • 2013-09-05
  • 2016-07-21
  • 2014-09-07
  • 2023-03-20
相关资源
最近更新 更多