2016-01-23 51 views
0

我目前正在寫一個小的虛擬節目,試圖得到正確使用讀出在C掛得到字節數。我做了一個名爲readdata的小函數來從文件描述符中讀取並存儲在緩衝區中,然後返回讀取的字節數。我的問題是我試圖正確地錯誤處理和陷阱的事情,以便沒有緩衝區溢出,但我一直在做一些事情。如何正確錯誤陷阱在C讀取從文件描述符

下面是測試儀:

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

#define BUFSIZE 10 

int readdata(int fd, char *buf, int bsize); 

int main(void) { 
    char buf[BUFSIZE]; 
    int returnval; 
    int length; 
    returnval = readdata(STDIN_FILENO, buf, BUFSIZE); 
    printf("%s",buf); 
    length = strlen(buf); 
    fprintf(stderr,"The return value is %d\n", returnval); 
    fprintf(stderr,"The string is %s\n",buf); 
    fprintf(stderr,"The length of the string is %d\n",length); 
    return 0; 
} 

這裏是小功能:

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

int readdata(int fd, char *buf, int bufsize){ 
    int n = 0; 
    if(fd < 0){ 
    return 1; 
    } 

    while((n=read(fd,buf,(bufsize-1)))>0){ 
     if(n == -1) { 
     perror("Read failed"); 
     return 1; 
     } 
     else{ 
     buf[bufsize] = 0; 
     return n; 
     } 
    } 
} 

如果我運行

cc -o test test.c readdata.c 

然後把

echo "Hello" | ./test 

它工作正常。但是,如果我通過了BUFSIZE限制這樣的:

echo "1234567891" | ./getdatatest 

它給了我這個奇怪的輸出,它說「的字符串爲123456789 [一些奇怪的符號]」。所以我不確定在哪裏處理這個錯誤,或者爲什麼它在讀取時仍然不正確地放入緩衝區。

+2

'BUF [BUFSIZE ] = 0;'調用未定義的行爲 – Olaf

+0

'read'和朋友通常用於讀取二進制數據,而不是文本文件。 –

+0

開始,'read()'在unistd.h中原型化,發佈的代碼沒有#include。因此,編譯器最好假設所有參數和返回類型都是'int'。建議將在包含'READDATA()'行文件的頂部:'#包括'然後更正調用'閱讀()'使用正確的參數和返回值的類型。爲了幫助你,原型是:'ssize_t供讀取(INT FD,無效* buf中,爲size_t計數);'強烈暗示了'READDATA()'函數應該返回一個'ssize_t',而不是一個'int' – user3629249

回答

1

你知道read()可以返回更少的字符比你要求的?此外,buf[bufsize]剛剛結束buf。你readdata功能也應該返回類似-1上的錯誤,而不是1這樣你就可以區分條件從「讀一個字節」

考慮這樣的事情「IO錯誤。」:

for (;;) { 
    n = read(fd, buf, (bufsize - 1)); 

    if(n == -1) { 
     perror("Read failed"); 
     return -1; 
    } else { 
     buf[n] = 0; 
     return n; 
    } 
} 
+0

的while()循環是檢查/退出如果返回的值<= 0,所以'if'代碼塊將永遠不會被輸入這個答案留下了很多不足之處 – user3629249

+0

@ user3629249謝謝你的評論。我稍微改進了答案。 – fuz