2016-01-23 47 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