2013-05-26 78 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

像魅力一樣工作!謝謝您的幫助! –