stdin和输入缓冲区的内部工作

时间:2013-01-21 13:53:55

标签: stdin outputstream gets

我试图在5秒内打印用户输入的字符数。但是我在获取输入缓冲区方面遇到了一些问题。

代码段


# include <signal.h>
# include <sys/time.h>
# define INTERVAL 3
# define MAX_SIZE 1024

char buffer[MAX_SIZE];
int count = 0;

void alarm_handler (int i)
{
    printf("\r\n");
    printf("\nTimer expired.....\r\n");
    count = read(stdin,buffer,sizeof(buffer));
    puts(buffer);
    printf("count:%d\r\n",strlen(buffer));
    exit(0);
}

int main()
{
    signal(SIGALRM,alarm_handler); 
    alarm(INTERVAL);
    setbuf(stdin, NULL);

    printf("Start Triggering....\r\n");
    while (1)
    {
        gets(buffer);
    }
    return;
}

在上面的代码中,我没有得到用户输入的输入,输出缓冲区始终为零。任何人都可以告诉我出了什么问题和解决方案  它?

输出

++++++

Start Triggering....

akakakakakkaka

Timer expired.....

count:0

但我期待以下输出

++++++++++++++++++++++++++++++

Start Triggering....

akakakakakkaka

Timer expired.....

akakakakakkaka

count:14

请就此提出建议。

1 个答案:

答案 0 :(得分:0)

缓冲和类似的事情非常复杂。我对你的问题采取了一种稍微不同的方法 - 设置终端,以便立即将键击传递给程序(而不是等到按下<enter>),并计算按键的次数。 这需要使用修改终端设置的函数getch()。请注意,我确保终端返回到“旧”设置,以防万一中断发生在“错误的时间”。

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/time.h>
#include <unistd.h>
#include <termios.h>
#define INTERVAL 3

int count = 0;
int flag = 0;
struct termios oldt; // keep old terminal settings to restore at the end

// function prototype - compiler was complaining. Not sure why?
unsigned int alarm(unsigned int interval);

void alarm_handler(int i) {
  flag = 1;
}

int getch(void)
{
  // function to return keystroke "as it happens"
  int ch;
  struct termios newt;
  tcgetattr(STDIN_FILENO, &oldt); /*store old settings */
  newt = oldt; /* copy old settings to new settings */
  newt.c_lflag &= ~(ICANON | ECHO); /* make one change to old settings in new settings */
  tcsetattr(STDIN_FILENO, TCSANOW, &newt); /*apply the new settings immediatly */
  ch = getchar(); /* standard getchar call */
  tcsetattr(STDIN_FILENO, TCSANOW, &oldt); /*reapply the old settings */
  return ch; /*return received char */
}

int main() {
  signal(SIGALRM,alarm_handler); 
  alarm(INTERVAL);

  printf("Start Triggering....\r\n");
  char c;
  do
    {
      c = getch(); // get key as soon as it's pressed
      putchar(c);  // and echo to the screen
      count++;     // increment counter
    } while (!flag);

  printf("\nTimed out!\nCharacter count = %d\n", count);
  tcsetattr(STDIN_FILENO, TCSANOW, &oldt); /*reapply the old settings */

  return 0;
}