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

'ЬиЕ [BUFSIZE ] = 0; 'вызывает неопределенное поведение. – Olaf

+0

' read' и друзья обычно используются для чтения двоичных данных, а не текстовых файлов. –

+0

, чтобы начать, 'read()' прототипирован в unistd.h, который опубликованный код не #include. Поэтому в лучшем случае компилятор примет все параметры, а тип возврата - 'int'. Предложите вставить в верхней части файла, содержащего 'readdata()' строку: '#include ', затем исправьте вызов' read() ', чтобы использовать соответствующие параметры и возвращаемые типы. Чтобы помочь вам, прототип: 'ssize_t read (int fd, void * buf, size_t count);' который сильно намекает на функцию 'readdata()', должен возвращать 'ssize_t', а не' int' – user3629249

ответ

1

Вы знаете, что read() может вернуть меньше символов, чем вы просили? Кроме того, buf[bufsize] только что закончил buf. Ваша readdata функция должна также возвращать что-то вроде -1 об ошибке вместо 1, так что вы можете отличить состояние «один байт для чтения» из

Рассмотрим что-то вроде этого «ошибка ввода-вывода.»:

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

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

цикл while() проверяет/exit, если возвращаемое значение <= 0, поэтому блок кода 'if' никогда не будет введен. IEэтот ответ оставляет желать лучшего. – user3629249

+0

@ user3629249 Спасибо за ваше замечание. Я немного улучшил ответ. – fuz

Смежные вопросы