【问题标题】:execute after EOF in C在 C 中的 EOF 之后执行
【发布时间】:2015-05-18 11:45:29
【问题描述】:

我正在为我的 C 编程课做作业。该问题指出“编写一个程序,将输入作为字符流读取,直到遇到 EOF”。我在我的 macbook 上使用 Xcode,我知道让程序遇到 EOF 的唯一方法是使用 ctrl + D 或 ctrl + Z。但它会完全退出我的程序。

例如我有这个代码:

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

    }
    printf("%d",ch);
    return 0;
}

在循环之后(在我按键盘上的 ctrl + D 之后)执行 printf("%d",ch) 的代码是否存在?

【问题讨论】:

  • 在按 Ctrl-D 之前,您必须至少按一次 Enter。
  • @PaulGriffiths 真的是这样吗?
  • @dattran 它应该打印 -1 或其他东西。你确定你没有因为 print 语句中缺少 \n 而错过了 o/p 吗?
  • 输出last输入字符的代码,恰好是EOF,因此是-1。
  • 要打印输入的ASCII码,将putchar(ch);改为printf("%d," ch);

标签: c input eof


【解决方案1】:

首先ctrl+z 不会在你的程序中输入EOF。如果您点击ctrl+Z,您的shell 将使您的程序进入睡眠状态。

其次,如果你想在你的程序中处理这些ctrl+Z,你需要学习C语言中的信号处理。

而且我认为因为您点击了ctrl+Z,所以您在屏幕上看不到任何输出。

【讨论】:

  • OP,CTRL+Z 在 Windows 中是 EOF
  • @AlterMann:OP 使用的是 Mac。
  • CTRL-D 在 Unix 和 Mac OSX 上是 EOF。处理CTRL-D时不涉及任何信号。
  • 那么输入EOF有不同的方法吗?不退出我的程序?
  • 停止使用诸如“CTRL-D is EOF”之类的短语。键入 Ctrl-D 只会关闭输入流。当输入流关闭时,getchar 返回一个恰好被指定为 'EOF' 的值,但说“发送了一个 eof”是不正确的。流已关闭。 EOS。 (故事结束)。
【解决方案2】:

您可以使用(使用 POSIX shell)here documents 测试您的程序。

首先将你的源代码mycode.c编译成二进制mybin

 gcc -std=c99 -Wall -Wextra -g mycode.c -o mybin

(可能是clangcc 而不是gcc

然后运行 ​​mybin 并使用“此处的文档”,例如

 ./mybin << EOF
    here is my 
    input
 EOF

您也可以使用输入重定向。创建一些文件myfile.txt 并运行./mybin &lt; myfile.txt

您甚至可以在自己的源代码上运行您的程序:./mybin &lt; mycode.c

输入甚至可能来自某个管道,例如ls * | ./mybin

顺便说一句,您观察到的是stdin,当它是一个终端时,是行缓冲的。见this answer(大部分应该适用于MacOSX)。

请注意您的代码不正确:您在文件顶部附近缺少#include &lt;stdio.h&gt;,而您的main 应该是int main(int argc, char**argv)(顺便说一句,您可以改进您的程序,以便在给出参数时,它们是要读取的文件名)。最后结尾printf肯定会显示-1,这通常是EOF的值

另外,最好用\n 结束您的printf 格式控制字符串,或者适当地使用fflush(3)

请注意,文件结尾不是输入(或有效的char),它是某些输入文件流(如stdin)和getchar(3) 函数的条件指定返回EOF,它是int 范围之外的char(在我的Linux 系统上EOF 是-1,因为char-s 包含在0 到255 之间)。您可以使用feof(3)

测试文件结束条件某些输入操作(从不之前!)

通常熟模式下的终端由内核处理,因此当您按下 Ctrl D 时,文件结束 条件 是在与该终端相关的文件描述符(通常为 STDIN_FILENO 即 0)上触发。

【讨论】:

    【解决方案3】:

    我在我的 macbook 上使用 Xcode,我知道让程序遇到 EOF 的唯一方法是使用 ctrl + D 或 ctrl + Z。但它会完全退出我的程序。

    不,不会的。如果您在 Xcode 调试器中运行程序,只要控制台窗格具有焦点,您输入的所有输入都将转到您的程序(请注意,默认情况下,stdin 是行缓冲的,因此您只会在按下时看到输出返回键)。如果你点击 control-d(不是 control-z),你的程序将退出循环并在控制台窗口中打印 -1(这是你所期望的,因为这是 OS X 中 EOF 的值)。

    这是我在 Xcode 调试器中运行您的程序时的结果(我在 Xcode 中输入了 command-r)

    bgbgdfsfd
    bgbgdfsfd
    hgfdgf
    hgfdgf
    -1

    常规字体是我输入的,粗体是来自您的程序。在我输入的每一行的末尾,我按回车键。在你的程序打印hgfdgf 之后,我输入了 control-D。然后你的程序打印了它从getchar() 得到的最后一件事的值,即EOF,也就是OS X C 库中的-1


    编辑

    如果您不确定您的程序是否正在打印 EOF,请将您的 printf 格式字符串更改为(例如)

    printf("Last character is [%d]\n", ch);
    

    那么你的程序将在最后一行输出Last character is [-1],而不是-1

    【讨论】:

    • 所以如果它得到EOF它应该退出循环并执行printf?你得到 printf 结果了吗?
    • @DatTran 是的,这就是输出末尾的-1
    【解决方案4】:

    确保您发送的是 EOF 信号,而不是实际终止程序的信号。

    例如,对于在 windows 中运行的 c 程序,EOF 是通过键入 ctrl+z 并按 enter 来表示的。这样做会退出您的 while 循环,但仍会运行程序的其余部分。

    但是,某些人可能错误地尝试使用 EOF 的 ctrl+c 实际上会杀死您的程序,并且会阻止您的 while 循环后面的代码执行。

    对于 mac,您需要找到与 EOF 对应的输入,并确保这是您发送的内容,而不是 kill 信号,我怀疑这是您在这里所做的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-12-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多