用C清除出标准输入时,它可能会或可能不会是空的 [英] Clearing out stdin in C when it may or may not be empty

查看:96
本文介绍了用C清除出标准输入时,它可能会或可能不会是空的的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是一名编程的学生在寻找一种方式来摆脱可以围绕悬在标准输入的字符。我曾尝试已此处给出各种形式,在那里你做这样的事情的一种技术:

I am a programming student looking for a way to get rid of characters that may be hanging around in stdin. I have tried a technique that has been given here in various forms, where you do something like this:

void clearStdIn(void) 
{
    char c;
    while((c = getchar()) != '\n' && c != EOF)
        /* discard */ ;
}

这个问题似乎是,如果没有在标准输入,首先,这个函数坐在那里等待用户键入回车前控制流可以继续前进。我该怎么办?

The problem seems to be that if nothing is in stdin to begin with, this function sits around waiting for the user to hit enter before control flow can move on. What should I do?

推荐答案

不阻塞冲洗的输入流(在一个可移植的方式)可以这样进行:

Flushing an input stream (in a portable way) without blocking could be done like this:

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>

int flush_inputstream(int fd)
{
  int result = 0;

  int flags = fcntl(fd, F_GETFL);
  if (-1 == flags)
  {
    perror("fcntl() failed getting flags");

    result = -1;
    goto lblExit;
  }

  if (!(flags & O_NONBLOCK)) /* If stream isn't non-blocking */
  {                          /* set it to be non-blocking. */
    result = fcntl(fd, F_SETFL, O_NONBLOCK);
    if (-1 == result)
    {
      perror("fcntl() failed setting O_NONBLOCK");

      goto lblExit;
    }
  }

  /* Loop reading from the stream until it is emtpy: */
  do
  {
    char c = 0;
    ssize_t bytesRead = read(fd, &c, 1);
    if (-1 == bytesRead)
    {
      if ((EAGAIN != errno) && (EWOULDBLOCK != errno))
      {
        perror("read() failed");

        result = -1;
      }

      break;
    }
  } while (1);

  if (!(flags & O_NONBLOCK)) /* If stream had not be non-blocking */
  {                          /* re-set it to not be non-blocking. */
    int result_fcntl = fcntl(fd, F_SETFL, flags & ~O_NONBLOCK);
    if (-1 == result_fcntl)
    {
      perror("fcntl() failed setting flags");

      if (0 == result) /* Do not overwrite prvious error! */
      {
        result = result_fcntl;
      }

      goto lblExit;
    }
  }

lblExit:

  return result;
}

/* To test this: */
int main(void)
{
  int fd = fileno(stdin);

  printf("Feed some chars via the keyboard now!\n");

  sleep(3);

  printf("Game Over! Press enter to see stdin is empty\n");

  if (-1 == flush_inputstream(fd))
  {
    fprintf(stderr, "flush_inputstream() failed");
    return EXIT_FAILURE;
  }

  char s[16] = "";
  if (NULL == fgets(s, sizeof(s), stdin))
  {
    perror("fgets() failed");
  }

  printf("%s\n", s);

  return EXIT_SUCCESS;
}

这篇关于用C清除出标准输入时,它可能会或可能不会是空的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆