2013-02-15 43 views
-2

使用系統調用在C瞭解,如何讀取CTRL-D序列之前的所有輸入?

#include <unistd.h> 

int main() 
{ 
    char data[128]; 
    while(read(0, data, 128) == 0){ 
    read = read(0, data, 128)+ read //counting the amount of chars read in 
} 

    exit(0); 
} 

我想輸入後按ctrl + d終止,這樣,用戶可以按ENTER鍵,它就會轉到新的線路。現在它不是那樣運作。

讀取返回一個整數,表示它讀取的字節數。一旦用戶按下ctrl + d,我將如何停止閱讀,換句話說,您可以在按下回車鍵的同時繼續閱讀,但只有按下ctrl + d時纔會停止閱讀,然後返回我讀取的字符數。

回答

1

這聽起來像你需要看看非緩衝輸入。 This site建議使用termios函數禁用規範(緩衝)輸入。以下是我使用他們提供的示例代碼編寫的內容。這將允許用戶輸入文本,直到讀取Ctrl-D信號(0x40),此時它將輸出讀取的字節數。

#include <unistd.h> 
#include <termios.h> 

void print_int(int num); 

int main() 
{ 
    struct termios old_tio, new_tio; 
    unsigned char c; 

    /* get the terminal settings for stdin */ 
    tcgetattr(STDIN_FILENO, &old_tio); 

    /* we want to keep the old setting to restore them a the end */ 
    new_tio = old_tio; 

    /* disable canonical mode (buffered i/o) and local echo */ 
    new_tio.c_lflag &=(~ICANON & ~ECHOCTL); 

    /* set the new settings immediately */ 
    tcsetattr(STDIN_FILENO, TCSANOW, &new_tio); 

    char buf[128] = {0}; 
    int curr = read(STDIN_FILENO, buf, 128); 
    int nbyte = curr; 
    while (curr && buf[0] != 0x04) { 
    curr = read(STDIN_FILENO, buf, 128); 
    nbyte += curr; 
    } 

    /* restore the former settings */ 
    tcsetattr(STDIN_FILENO, TCSANOW, &old_tio); 

    write(STDOUT_FILENO, "Total bytes: ", 13); 
    print_int(nbyte); 
    write(STDOUT_FILENO, "\n", 1); 

    return 0; 
} 

void print_int(int num) { 
    char temp[16]; 
    int i = 0, max; 
    while (num > 0) { 
    temp[i++] = '0'+(num % 10); 
    num /= 10; 
    } 
    max = i; 
    for (i=(max-1); i>=0; i--) { 
    write(STDOUT_FILENO, &temp[i], 1); 
    } 
} 

注意,在他們的示例代碼,他們使用~ECHO,但我相信你想看到的輸入您所輸入的,所以~ECHOCTL將只禁用呼應控制字符(例如,^ d在年底輸入)。

+1

[只有鏈路的答案是高度氣餒對堆棧溢出(http://meta.stackexchange.com/questions/8231/are-answers-that-just-contain-links-elsewhere-really-good -answers)。請擴大。 – netcoder 2013-02-15 17:12:05

+0

@adamdunson我不能使用libc,這對我來說沒有意義。應該有一個更簡單,直接的方法來做到這一點。 – markf 2013-02-15 17:15:00

+0

@netcoder - 除了當他們受到這裏最高貢獻者的鼓勵時。 – 2013-02-15 17:15:04

1

與端子,插座或管道等數據源一起使用時,read一旦有一些數據準備好就會返回。終端驅動程序通常會逐行提供數據,這就是您的程序所獲得的。

如果您想要讀取特定數量的數據,或讀取所有數據,直到滿足特定條件,則必須在循環中執行此操作。

+0

一旦控件d被擊中,我會如何告訴循環停止? – markf 2013-02-15 17:15:43

+0

'read'在文件結束時返回0。 – 2013-02-15 17:19:05

+0

你可以給我一個例子n.m,一個基於我的代碼的簡單例子。 – markf 2013-02-15 17:20:10

0
int c; 
while((c = getchar()) != EOF) { 
    /*do something*/ 
} 
相關問題