简体   繁体   English

在C中的EOF之后执行

[英]execute after EOF in C

I'm doing homework for my C programming class. 我正在为C编程课做作业。 The question states "Write a program which reads input as a stream of characters until encountering EOF". 问题指出“编写一个程序,该程序以字符流的形式读取输入,直到遇到EOF为止”。 I'm using Xcode on my macbook and the only way I know to make the program encounter EOF is using ctrl + D or ctrl + Z. But it will exit my program completely. 我在Macbook上使用Xcode,我知道使程序遇到EOF的唯一方法是使用ctrl + D或ctrl +Z。但是它将完全退出我的程序。

For example I have this code: 例如,我有以下代码:

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

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

Is there away for the code to execute the printf("%d",ch) after the loop (after i hit ctrl + D on my keyboard)? 循环后(在我按下键盘上的Ctrl + D之后),是否有代码可以执行printf(“%d”,ch)?

You can test your program using (with a POSIX shell) here documents . 您可以使用(在POSIX shell中) 此处文档测试程序。

First compile your source code mycode.c into a binary mybin with 首先使用以下命令将源代码mycode.c编译为二进制mybin

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

(it could be clang or cc instead of gcc ) (它可以是clangcc而不是gcc

then run mybin with a "here document" like 然后用“ here document”运行mybin

 ./mybin << EOF
    here is my 
    input
 EOF

You could also use input redirection. 您也可以使用输入重定向。 Make some file myfile.txt and run ./mybin < myfile.txt 创建一些文件myfile.txt并运行./mybin < myfile.txt

You could even run your program on its own source code: ./mybin < mycode.c 您甚至可以在自己的源代码上运行程序: ./mybin < mycode.c

And the input could even come from some pipe, eg ls * | ./mybin 输入甚至可以来自某些管道,例如ls * | ./mybin ls * | ./mybin

BTW, what you are observing is that stdin , when it is a terminal, is line-buffered. 顺便说一句,您正在观察的是stdin (当它是终端时)是行缓冲的。 See this answer (most of it should apply to MacOSX). 查看此答案 (大多数答案应适用于MacOSX)。

Notice that your code is incorrect: you are missing an #include <stdio.h> near the top of the file, and your main should really be int main(int argc, char**argv) (BTW you could improve your program so that when arguments are given, they are file names to be read). 请注意,您的代码是不正确的:您在文件顶部附近缺少#include <stdio.h> ,并且您的main实际上应该是int main(int argc, char**argv) (顺便说一句,您可以改进程序,以便给出参数时,它们就是要读取的文件名)。 At last the ending printf would surely show -1 which is generally the value of EOF 最后, printf末尾肯定会显示-1,这通常是EOF的值

Also, it is much better to end your printf format control string with \\n or else use appropriately fflush(3) 另外,最好以\\n结尾您的printf格式控制字符串,或者使用适当的fflush(3)

Notice that end-of-file is not an input (or a valid char ), it is a condition on some input file stream like stdin , and the getchar(3) function is specified to return EOF which is an int outside of the range of char (on my Linux system EOF is -1 because char -s are between 0 and 255 included). 请注意,文件结尾不是输入(或有效char ),它是某些输入文件流(例如stdin )的条件,并且指定了getchar(3)函数以返回EOF ,该EOF是范围之外的int char (在我的Linux系统上, EOF为-1,因为char -s在0到255之间)。 You might test end-of-file condition after some input operation ( never before!) using feof(3) 您可以使用feof(3) 在进行一些输入操作( 从未有过!) 之后测试文件结束条件

A terminal in usual cooked mode is handled by the kernel so that when you press Ctrl D an end-of-file condition is triggered on the file descriptor (often STDIN_FILENO ie 0) related to that terminal. 处于正常烹饪模式的终端由内核处理,因此当您按Ctrl D时,在与该终端相关的文件描述符(通常为STDIN_FILENO即0)上触发文件结束条件

I'm using Xcode on my macbook and the only way I know to make the program encounter EOF is using ctrl + D or ctrl + Z. But it will exit my program completely. 我在Macbook上使用Xcode,我知道使程序遇到EOF的唯一方法是使用ctrl + D或ctrl +Z。但是它将完全退出我的程序。

No it won't. 不,不会。 If you run your program in the Xcode debugger, provided the console pane has the focus, all input you type will go to your program (note that, by default, stdin is line buffered, so you'll only see output when you press the return key). 如果您在Xcode调试器中运行程序,只要控制台窗格具有焦点,您键入的所有输入都将进入您的程序(请注意,默认情况下,stdin是行缓冲的,因此,只有在按返回键)。 If you hit control-d (not control-z), you're program will exit the loop and print -1 in the console window (which is what you expect because that is the value of EOF in OS X). 如果您按Control-d(而不是Control-z),则程序将退出循环并在控制台窗口中显示-1(这是您期望的,因为这是OS X中EOF的值)。

Here is the result when I ran your program without change in the Xcode debugger (I typed command-r in Xcode) 这是我在Xcode调试器中运行但未更改的程序的结果(我在Xcode中键入command-r)

bgbgdfsfd
bgbgdfsfd
hgfdgf
hgfdgf
-1

Regular font was typed by me, bold font was from your program. 我输入的是常规字体,粗体来自您的程序。 At the end of each of the lines typed by me, I pressed carriage return. 在我键入的每一行的末尾,我按回车键。 After your program printed hgfdgf I typed control-D. 在您的程序打印hgfdgf我键入了control-D。 Your program then printed the value of the last thing it got from getchar() which was EOF which is -1 in the OS XC library. 然后,您的程序打印了从getchar()获得的最后一个值,该值在OS XC库中为EOF ,即为-1


Edit 编辑

If you are unsure that your program is printing the EOF, change your printf format string to (for example) 如果不确定您的程序正在打印EOF,请将您的printf格式字符串更改为(例如)

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

Then instead of -1 your program will output Last character is [-1] on the last line. 然后,程序将在最后一行输出Last character is [-1] ,而不是-1

First of all ctrl+z does not input EOF to your program. 首先ctrl+z不会在程序中输入EOF。 If you hit ctrl+Z your shell will put your program to sleep. 如果您按ctrl+Z shell将使程序进入睡眠状态。

Second, if you want to handle these ctrl+Z in your program you need to learn about signal handling in C. 其次,如果要在程序中处理这些ctrl+Z ,则需要学习C语言中的信号处理。

And I think because you were hitting ctrl+Z you were not seeing any output on the screen. 而且我认为,因为您按的是ctrl+Z您在屏幕上看不到任何输出。

Make sure you are sending the EOF signal, not a signal that actually terminates your program. 确保发送的是EOF信号,而不是实际终止程序的信号。

For example, for c program running in windows the EOF is represent by typing ctrl+z and pressing enter. 例如,对于在Windows中运行的c程序,通过键入ctrl + z并按Enter表示EOF。 Doing this will exit your while loop but still runs the rest of your program. 这样做将退出while循环,但仍将运行其余程序。

However, ctrl+c, which some people may have mistakenly tried for EOF, actually kills your program and will prevent the code behind your while loop from executing. 但是,某些人可能为EOF尝试了错误的ctrl + c,实际上杀死了您的程序,并阻止了while循环后面的代码执行。

For mac you will need to find what is the input that corresponds to EOF, and make sure that is what you are sending through rather than the kill signal, which I suspect is what you are doing here. 对于Mac,您将需要查找对应于EOF的输入,并确保这是您通过发送的内容,而不是kill信号,我怀疑这是您在此处执行的操作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM