【问题标题】:Exit a loop when stdin is EOF in C?当stdin是C中的EOF时退出循环?
【发布时间】:2014-06-09 21:46:49
【问题描述】:

我怎样才能跳出这个循环?

while(1){
    //continuously blink an led
    //stop when user hits CTRL+D
}
//do other stuff

我尝试了while(fgets(s, BUFSIZ, stdin) != NULL),但它当然会在继续之前等待用户输入。我希望循环内的代码连续运行,并且只中断用户点击CTRL+D

我已经通过中断在低级别完成了此操作,但不知道如何在高级环境中执行此操作。

平台是 Raspberry Pi 上的 Raspbian(内核 3.10)

【问题讨论】:

  • 特定于 Windows 的答案能否满足您的需求?
  • @ThoAppelsin Linux 答案将是理想的,最好是 Raspbian - 我已经更新了我的问题。
  • 嗯,“我怎样才能跳出这个循环?”的字面意思。是break;...听起来您的问题应该更像是“如何在stdin 上检测EOF?”...

标签: c raspberry-pi raspbian


【解决方案1】:

正如@unwind 所说,您可以使用select

#include <sys/select.h>
#include <unistd.h>
#include <string.h>

int main()
{
   int run = 1, rc;
   fd_set fd_list, readfd;

   FD_ZERO(&fd_list);
   FD_SET(STDIN_FILENO, &fd_list);

   while (run)
  {
    readfd = fd_list;
    rc = select(STDIN_FILENO + 1, &readfd, NULL, NULL, NULL);

    if (rc == -1)
    {
        perror("Select error");
      return 1;
    }

    if (FD_ISSET(STDIN_FILENO, &readfd) && read(STDIN_FILENO, &rc, sizeof(rc)) == 0 )
      run = 0;

  }

  return 0;
}

我们已经告诉 select 监视仅读取一个 fd(STDIN_FILENO):标准输入之一。
一旦用户输入内容,select 会提醒我们该事件;我们调查以了解该输入是否来自 STDIN_FILENO,如果是,我们从它read。如果read 返回 0,则表示文件结束。

【讨论】:

    【解决方案2】:

    也许这种使用术语上限将Ctrl+D 转换为Ctrl+CCtrl+C 转换为Ctrl+D 的解决方案可能会对您有所帮助:https://stackoverflow.com/a/1516414/1405208

    Ctrl+D 因此将发送SIGINT 信号。你只需要抓住它。不过,您可能必须使用全局变量。

    volatile sig_atomic_t ctrld_pressed = 0;
    
    void ctrld(int sig)
    {
      ctrld_pressed = 1;
    }
    
    int main()
    {
        signal(SIGINT, ctrld);
        while (!ctrld_pressed)
        {
    
        }
    }
    

    【讨论】:

    • 变量ctrld_pressed的类型应该是volatile sig_atomic_t
    • @black 编辑了我的答案,虽然这不是强制性的(我想让我的答案保持简单),但使用它总是更好。
    【解决方案3】:

    如果您的平台支持,您可以尝试使用select(),否则您必须将输入流设为非阻塞(“原始”),这又是高度依赖于平台的代码。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-09-14
      • 1970-01-01
      • 2016-01-19
      • 1970-01-01
      • 2022-01-13
      • 1970-01-01
      • 2014-04-12
      相关资源
      最近更新 更多