C语言 在 C 中检测 Ctrl-D

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/35823864/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 10:21:15  来源:igfitidea点击:

Detecting Ctrl-D in C

cstdinexitfgetsctrl

提问by Melissa Ding

I am trying to detect the Ctrl+Duser input, which I know returns EOF. Right now, I know the code waits for input from the stdin stream, but is there a way to let the program continue until the Ctrl+Dcommand is in stdin? The program should continue running past the if statement if Ctrl+Disn't inputted.

我正在尝试检测Ctrl+D用户输入,我知道它返回EOF. 现在,我知道代码等待来自 stdin 流的输入,但是有没有办法让程序继续运行,直到Ctrl+D命令在 stdin 中?如果Ctrl+D没有输入,程序应该继续运行超过 if 语句。

char buffer[];
if (fgets(buffer, 10, stdin) == NULL{
    //write to file
}

回答by JojOatXGME

You want to stop a program when the user is pressing Ctrl+D? But you don't want to read stdin? If this is true, you should consider if a handler for Ctrl+Cwould be a better solution. But first I will write something about non-blocking I/O, since this is what you are asking for.

您想在用户按下Ctrl+时停止程序D吗?但是您不想阅读stdin吗?如果这是真的,您应该考虑Ctrl+的处理程序C是否是更好的解决方案。但首先我会写一些关于非阻塞 I/O 的东西,因为这就是你所要求的。



There is no standard way to achieve nonblocking I/O in C. But you could use POSIX-functions like selector fcntlin combination with read. There are other questions about it on StackOverflow. This questionfor example.

C 中没有实现非阻塞 I/O 的标准方法。但是您可以使用POSIX函数,例如selectfcntlread. StackOverflow 上还有其他关于它的问题。例如这个问题



If you want to handle Ctrl+C, you can use signalto do something like this:

如果你想处理Ctrl+ C,你可以用signal做这样的事情:

#include <signal.h>
#include <stdio.h>
#include <stdlib.h>

volatile bool shouldRun = true;

void sighandler(int) {
    shouldRun = false;
}

int main(int argc, char *argv[]) {
    if (signal(SIGINT, &sighandler) == SIG_ERR) {
        fprintf(stderr, "Could not set signal handler\n");
        return EXIT_FAILURE;
    }

    printf("Program started\n");
    while (shouldRun) {
        // Do something...
    }
    printf("Program is shutting down.\n");
    return EXIT_SUCCESS;
}

回答by Vlad

Since the machine generates EOFon Ctrl+D, you should be checking fgets()for NULL, as fgets()is obliged to return NULLon end of file.

由于机器产生EOFCtrl+ D,你应该检查fgets()NULL,因为fgets()有义务回报NULL在文件末尾。

line = fgets(l, BUFFSIZE, stdin)
if (line == NULL)
    continue;

回答by texasbruce

It is too much to post here and you are not specific what you have currently and what you want. So here gives you a general idea of how to do it:

在这里发帖太多了,而且您没有具体说明您目前拥有什么以及想要什么。因此,这里为您提供了如何做到这一点的总体思路:

  1. Put that if statement inside a forked process or other thread
  2. Send a posix signal to your (parent) process when the key is captured
  3. Add signal handler in your program

    If you just wanna terminate the program when C-d is entered, just send a SIGKILL in step 2 and ignore step 3.

  1. 将该 if 语句放在分叉进程或其他线程中
  2. 捕获密钥时向您的(父)进程发送 posix 信号
  3. 在程序中添加信号处理程序

    如果您只想在输入 Cd 时终止程序,只需在步骤 2 中发送 SIGKILL 并忽略步骤 3。

If you do not know any term above, Google is your friend

如果你不知道上面的任何术语,谷歌是你的朋友

回答by Silas S. Brown

On most operating systems, stdin is buffered one line at a time, and any attempt to read it (without going into low-level nasties) will stop until either a line or EOF is available. If you don't mind this, and just want to check for EOF without reading-in any waiting input if EOF is not present, you could use ungetc:

在大多数操作系统上,stdin 一次缓冲一行,并且任何读取它的尝试(不进入低级别的麻烦)都将停止,直到一行或 EOF 可用。如果您不介意这一点,并且只想在不存在 EOF 的情况下检查 EOF 而不读入任何等待输入,则可以使用 ungetc:

#include <stdio.h>

int check_for_EOF() {
    if (feof(stdin)) return 1;
    int c = getc(stdin);
    if (c == EOF) return 1;
    ungetc(c, stdin);
}

int main() {
    printf("Start typing:\n");
    while (!check_for_EOF()) {
        int bytes_typed = 0;
        while (getchar() != '\n') bytes_typed++;
        printf("You typed a line of %d bytes\n", bytes_typed);
    }
    printf("You typed EOF\n");
}

You are only guaranteed one character of push-back from ungetc, although most implementations give you much more. And it works only if you're not going to seek the stream later (which is the case with stdin). Notice also that I'm calling it "bytes typed", not "characters typed": Chinese, Japanese and Korean characters for example cannot fit into the char type of most C implementations, and it would depend how the console encodes them when you type (if you have a CJK input method set up or can copy/paste some, you can try it on the above program and see).

尽管大多数实现为您提供了更多,但您只能保证从 ungetc 回退一个字符。并且只有在您以后不打算查找流时才有效(标准输入就是这种情况)。另请注意,我将其称为“字节类型”,而不是“字符类型”:例如,中文、日文和韩文字符无法适应大多数 C 实现的 char 类型,这取决于您键入时控制台如何对它们进行编码(如果你设置了 CJK 输入法或者可以复制/粘贴一些,你可以在上面的程序上试试看)。