стандартный ввод EOF после первой строки - PullRequest
0 голосов
/ 08 июля 2019

Я пытаюсь передать файл в мою программу, используя type file.txt | myprogram.exe.Я читаю это с помощью:

char *line;
struct block *newblock, *cur;
int i, osl, cbs, rs;
int startblock;

/* read in the blocks ... */
while (!feof(stdin) && !ferror(stdin)) {
    cbs = 2048;
    line = (char *)malloc(cbs + 1);
    if (!line) {
        perror("malloc");
        exit(1);
    }
    line[cbs] = '\0';

    /* read in the line */
    if (!fgets(line, cbs, stdin)) {
        free(line);
        continue;
    } else {
        while (line[cbs - 2]) {
            /* expand the line */
            line = (char *)realloc(line, (cbs * 2) + 1);
            if (!line) {
                perror("realloc");
                exit(1);
            }
            line[cbs * 2] = '\0';

            /* read more */
            if (!fgets(line + cbs - 1, cbs + 1, stdin))
                break;

            cbs *= 2;
        }
    }
    ...
}

Но только после прочтения первой строки, feof() возвращает true, даже если в файле несколько строк.Как это может случиться?

1 Ответ

1 голос
/ 08 июля 2019

Код имеет несколько проблем:

  • тест конца файла неверен: feof() предоставляет только значимую информацию после сбой функции чтения.
  • схема перераспределения нарушена: вы проверяете второй-последний байт массива, но fgets() может не установить этот байт, если строка короче.

Вот как вы можете это сделатьисправьте вашу программу:

  • либо используйте getline(), если ваша система поддерживает это.getline() выделяет достаточно большой буфер для одновременного чтения полной строки.
  • или используйте fgets для чтения фрагмента строки и проверки, заканчивается ли он новой строкой.
...