2013-05-26 57 views
1

我正在使用Lubuntu和LXterminal。C termios和printf问题

我有(从某种意义上)晦涩地从stack overflow answer中复制了此代码的基础,该代码给出了关于c非阻塞键盘输入的详细信息。

这是第一部分:

#include <stdlib.h> 
#include <stdio.h> 
#include <string.h> 
#include <unistd.h> 
#include <sys/select.h> 
#include <termios.h> 

using namespace std; 

struct termios orig_termios; 

void reset_terminal_mode() 
{ 
    tcsetattr(0, TCSANOW, &orig_termios); 
} 

void set_conio_terminal_mode() 
{ 
    struct termios new_termios; 

    /* take two copies - one for now, one for later */ 
    tcgetattr(0, &orig_termios); 
    memcpy(&new_termios, &orig_termios, sizeof(new_termios)); 

    /* register cleanup handler, and set the new terminal mode */ 
    atexit(reset_terminal_mode); 
    cfmakeraw(&new_termios); 
    tcsetattr(0, TCSANOW, &new_termios); 
} 

int kbhit() 
{ 
    struct timeval tv = { 0L, 0L }; 
    fd_set fds; 
    FD_ZERO(&fds); 
    FD_SET(0, &fds); 
    return select(1, &fds, NULL, NULL, &tv); 
} 

int getch() 
{ 
    int r; 
    unsigned char c; 
    if ((r = read(0, &c, sizeof(c))) < 0) { 
     return r; 
    } else { 
     return c; 
    } 
} 

这里是一个主要功能显示了一些奇怪的行为。

int main(int argc, char *argv[]) 
{ 
    unsigned int stor; 

    set_conio_terminal_mode(); 

    for(int i = 0; i < 6; i++){ 
      while (!kbhit()) {} /* wait */ 
      stor = getch(); /* consume the character */ 

      reset_terminal_mode(); 

      printf("\033[38;33m%i \033[38;0m", stor); 

      set_conio_terminal_mode(); 
    } 

    printf("more text\n"); 

} 

什么这个主循环的作用是它得到6个字符块(例如:输入6倍或箭头键两次。)但是,如果它说的printf没有打印输出,直至程序完成。

这可以当你添加

while(1){} 

到主函数的结尾可以看到更好。

那么这里发生了什么?发布所有printf函数的程序结束时是否会出现某种魔法?

当程序仍在运行时,如何使它成为printf?

+1

'printf'是缓冲输出,所以你应该关闭缓冲('函数setbuf(标准输出,NULL);')或在每个printf之后刷新它('fflush(stdout);')。 –

回答

1

显然,你是过度缓冲的受害者。使用setvbuf尝试禁用缓冲。

要完全在stdout禁用缓存:

setvbuf(stdout, (char *)NULL, _IONBF, 0); 

为了使每个行缓冲:

setvbuf(stdout, (char *)NULL, _IOLBF, 0); 
// or 
setlinebuf(stdout); 
+0

像魅力一样工作!谢谢您的帮助! –