Проблема с Fread при чтении из стандартного ввода для системы и ручного ввода - PullRequest
0 голосов
/ 15 декабря 2011

Приложение считывает входные данные из стандартного ввода, и функция выглядит следующим образом:

filepos = ftell(stdin);
if (filepos < 0 && errno != 0)
{
    perror("ftell");
    return 1;
}
if ((n = fread(input_data, sizeof(char), 2, stdin)) != 2)
{
    if (n == 1)
    {
        if (*input_data == '\n')
            fprintf(stderr, "Unexpected NL character read\n");
        else if (*input_data== '\r')
            fprintf(stderr, "Unexpected CR character read\n");
        else
            fprintf(stderr, "Unexpected character read <%c>\n", *input_data);
    }
    else if (n != 0 && errno != 0)
    {
        perror("fread");
    }
    return 1;
}
    ... process data ....

Когда я запускаю это по сгенерированному системой вводу, приложение обрабатывается правильно, и когда я запускаю это для того же вывода, которыйсоздается вручную, я получаю сообщение об ошибке «Неожиданное чтение символа NL».

$ convertInput < input.system > out
$
$ convertInput < input.manual > out
Unexpected NL character read
$

В обоих случаях вывод правильный.

Когда я сделал различие между двумя входамифайлы, он показал сообщение, как показано ниже.

$ diff input.manual input.system
1c1
< INPUT
---
> INPUT
\ No newline at end of file

Я проверил файл ручного ввода, и после ввода новой строки также нет. Я не уверен, следует ли заменять сам fread на fgets иличто-то, чтобы это исправить.

GDB показал, что "fread" возвратил "0" после окончания INPUT для "input.system", где как "fread" возвратил "\ n" после окончания INPUTдля «input.manual».

Файл руководства создается как «vim input», «вставляет» данные и удаляет все символы после окончания данных (включая «\ n») и «save and qui».т "редактор.

Любые предложения или мысли, чтобы исправить это приветствуется.

Спасибо,

1 Ответ

0 голосов
/ 15 декабря 2011

Проблема зависит от способа создания «ручного» файла. Если вы используете текстовый редактор (vim), обычно он ставит \ n на самом последнем месте, так как он должен завершать последнюю «текстовую» строку. Я предпочел бы использовать бинарный редактор, чтобы сделать работу. Насколько я помню, в последних версиях vim есть "бинарный режим". Другой способ создать файл, который пропускает последний \ n, - использовать "echo -en '... your data ...'> file". Опции -n опускают \ n, а -e интерпретирует последовательность символов, начинающуюся с "\" (например, "\ n", "\ r" ...). Я надеюсь, что это может помочь.

Кстати, «ftell» в stdin может возвращать бесполезные значения, если stdin не перенаправлен в реальный файл.

...