2014-11-15 485 views
2

我想讀取帶字符的數字字符,但我不知道stdin緩衝區是否爲空。檢查stdin緩衝區是否爲空

我的第一個解決方案是在標準緩衝區中尋找'\ n'字符,但是如果我輸入用''(空格)分隔的多個數字,這是不好的。

如何知道stdin緩衝區中是否有字符?

我不想在C中做到這一點,並且要攜帶。

+1

嘗試「的人選擇」 –

+0

檢查EOF。 (它實際上並不是一個字符,但是如果數據流是空的,它將返回值。) – UncleO

回答

1

有很多soutions的:

feof優選一個用於檢查是否緩衝器是空的。

if (!feof(stdin)) // Check if the stdin is empty 
    // read stuff 

pollselect以0超時 - 這將立即返回與結果爲-1,並將errno EAGAIN如果沒有可用的或數據的描述符的數量的數據(一個,因爲你只檢查標準輸入)。

ioctl是使用描述符的瑞士軍刀。你所需要的要求是I_NREAD

if (ioctl(0, I_NREAD, &n) == 0 && n > 0) 
    // we have exactly n bytes to read 

然而,正確的辦法是看你有(使用scanf)作爲樣樣在行,然後處理結果 - 這工作不夠好,與sscanf

char buf[80]; // large enough 
scanf("%79s", buf); // read everything we have in stdin 
if (sscanf(buf, "%d", &number) == 1) 
    // we have a number 

...只要你正確處理重讀,比你的緩衝區更長的字符串,以及其他現實生活中的複雜情況。

+1

如果我正在嘗試類似這樣的操作,則可以使用下面的代碼: c = getchar(); 012charputchar(c); }' whill進入一個無限循環 – Tandura

+0

函數'poll' /'select' /'ioctl'不會工作eather,因爲我需要一個不包含在標準IDE中的新庫(我使用的Code :: Blocks大學),所以解決方案仍然是第三個用buff讀取它並檢查buf長度是否爲80(在這種情況下),那麼我必須繼續閱讀 – Tandura

+1

如果你的stdin是從控制檯讀取的,那麼只有在你使用EOF就我所知發送EOF字符,它是'ctrl + d'。 'poll','select','ioctl'都是POSIX的函數,......討論它是否應該放在任何系統上都是無關緊要的。另一方面'sscanf'解決方案應該可以工作。 – aragaer

2

對於任何人誰到這裏從谷歌 - 易select的解決方案,以檢查stdin emptyness:

fd_set readfds; 
FD_ZERO(&readfds); 
FD_SET(STDIN_FILENO, &readfds); 
fd_set savefds = readfds; 

struct timeval timeout; 
timeout.tv_sec = 0; 
timeout.tv_usec = 0; 

int chr; 

if (select(1, &readfds, NULL, NULL, &timeout)) { 
    puts("Input:"); 
    while ((chr = getchar()) != EOF) putchar(chr); 
} 
readfds = savefds; 

需要unistd.hstdlib.hstdio.h

說明可以找到here

+0

適用於Linux,但不適用於Windows(它需要可移植) – Tandura

+0

@任何POSIX兼容系統上的Tandura。通常在Windows上,您必須使用不適用於其他系統的特定方法。所以我認爲任何* nix都比Windows更好。但是,它不是完全便攜的。 Idk在Windows上如何做到這一點,也許你知道? – stek29

2

我從this啓發由@stek29's post此頁面上引用,並準備一個簡單的例子如下:

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 

int main(void) 
{ 
    fd_set readfds; 
    FD_ZERO(&readfds); 

    struct timeval timeout; 
    timeout.tv_sec = 0; 
    timeout.tv_usec = 0; 

    char message[50]; 

    while(1) 
    { 
     FD_SET(STDIN_FILENO, &readfds); 

     if (select(1, &readfds, NULL, NULL, &timeout)) 
     { 
      scanf("%s", message); 
      printf("Message: %s\n", message); 
     } 

     printf("...\n"); 
     sleep(1); 
    } 

    return(0); 
} 
+0

適合我!我用'usleep(10)'取代了睡眠;'並刪除了printf(「... \ n」);' – datahaki