2015-09-26 20 views
1

我們剛剛開始了C語言中低級函數的主題,對於這部分任務我們必須要求用戶輸入。通常我會使用printf()和scanf(),但是對於這個任務我們只允許使用read(),write(),open(),close()和lseek()。使用無緩衝IO例程詢問和讀取用戶輸入

我的問題是如何在打印到屏幕後從鍵盤讀取輸入? 據我所知,我將不得不使用read,文件描述符將是STDIN_FILENO,但我如何確定大小計數?另外我將如何跟蹤用戶輸入的內容?我需要爲此創建一個char數組嗎?

此外,如果任何人都可以參考一些很好的閱讀材料或編程與低級別的功能,這將有助於很多教程。

+0

最簡單的方法可能一次只讀一個字符如果你得到一個換行符,將字符附加到數組中。 –

+0

如果你想從標準輸入讀取,你不需要事先指定數組的大小嗎?我明白你的意思,但我不知道如何實施它。 – user3538161

+0

使用'read/write'來完成輸入/輸出和使用'getchar/printf'確實沒有什麼區別。主要區別是您不喜歡格式化輸出或可變打印功能。您必須按照您希望的輸出方式將每個輸出寫入'stdout'來進行格式化。如果你仍然堅持讓我知道。你可以像使用任何文件一樣在'stdin'上使用read。你聲明一個緩衝區(數組)並從'stdin'讀入緩衝區。 'read'返回給你成功讀取的字符數。 –

回答

1

從我先前的評論繼續,存在使用readwrite和使用像fgetsprintf更高層次的功能,以stdin閱讀和寫作之間的真正差別不大。主要區別在於,您不能依賴可變參數printf提供的格式字符串以及read,因此您有責任使用返回來知道實際讀取了多少個字符。

下面是表示從stdinread讀取輸入,然後編寫信息反饋與write注意基礎知識很短的例子:有你應該增加像檢查的字符數讀額外的檢查小於知道是否還有更多字符需要讀取的緩衝區的大小等等)。您可以將大部分提示和read放入一個函數中,以緩解重複使用。

隨着write,只記得,你寫的東西stdout的順序是的格式字符串。因此只需簡單地調用write即可完成您所需的格式。雖然您可以自由使用STDIN_FILENO定義,你也可以簡單地使用0 - stdin1 - stdout2 - stderr

#include <unistd.h> 

#define MAXC 256 

int main (void) { 

    char buf[MAXC] = {0}; 
    ssize_t nchr = 0; 

    /* write the prompt to stdout requesting input */ 
    write (1, "\n enter text : ", sizeof ("\n enter text : ")); 

    /* read up to MAXC characters from stdin */ 
    if ((nchr = read (0, buf, MAXC)) == -1) { 
     write (2, "error: read failure.\n", sizeof ("error: read failure.\n")); 
     return 1; 
    } 

    /* test if additional characters remain unread in stdin */ 
    if (nchr == MAXC && buf[nchr - 1] != '\n') 
     write (2, "warning: additional chars remain unread.\n", 
      sizeof ("warning: additional chars remain unread.\n")); 

    /* write the contents of buf to stdout */ 
    write (1, "\n text entered: ", sizeof ("\n text entered: ")); 
    write (1, buf, nchr-1); 
    write (1, "\n\n", sizeof ("\n\n")); 

    return 0; 
} 

編譯

gcc -Wall -Wextra -o bin/read_write_stdin read_write_stdin.c 

輸出

$ ./bin/read_write_stdin 

enter text : The quick brown fox jumps over the lazy dog! 

text entered: The quick brown fox jumps over the lazy dog! 
+0

我對寫有點困惑。第二個參數不是一個指向緩衝區的指針嗎?你怎麼能傳遞一個字符串?當它到達文件末尾時也不讀取返回0?所以不會nchr = 0? – user3538161

+0

這是一個指向緩衝區的指針。該緩衝區被聲明爲一個靜態數組'buf [MAXC]'。但是,當作爲參數傳遞時,數組*會衰減*爲指針。這就是你可以寫'int main(int argc,char * argv [])'或'int main(int argc,char ** argv)'的原因。您可以閱讀關於該主題的所有內容,只需搜索** C指針衰減**即可。我簡單地選擇了一個靜態數組來保持示例簡單,而不是選擇使用'malloc'動態分配一個指針,並從'read''write'邏輯分散注意力。 ('calloc'會是更好的選擇)。 –

2

通過字符讀取字符會對性能不利。系統調用很貴。大多數情況下,你想要某種緩衝區(堆棧中的malloced,靜態內存)。 尺寸(一旦超過一定的尺寸)並不重要。

如果您的fd 0是熟食模式下的終端,您將在每次讀取呼叫時獲得一行(通常無法填充整個緩衝區)。重要的是要實現一個N字節的讀取請求不需要返回N個字節,而少於N個字節的返回不需要意味着IO錯誤。如果它是一個基於磁盤的文件,那麼您的緩衝區大小的讀取請求將得到充分填充。

Unix環境下的高級編程Richard Stevens是一本關於此的好書。 然後,當然,系統調用的手冊頁。