Clearing out stdin in C when it may or may not be empty

后端 未结 3 1842
北荒
北荒 2021-01-22 14:38

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, wh

3条回答
  •  星月不相逢
    2021-01-22 15:12

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

    #include 
    #include 
    #include 
    #include 
    #include 
    
    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;
    }
    

提交回复
热议问题