Стандартный вывод зависает после добавления оператора fprintf () с пользовательской стандартной ошибкой - PullRequest
2 голосов
/ 19 января 2012

У меня есть класс C ++ Archive с функцией-членом extractData().Эта функция вызывает realExtractData(), которая реализована в отдельной C-библиотеке.

Я хочу передать функции extractData() пару FILE * экземпляров, которые обычно stdout и stderr, но я также хочу предоставить возможность пользовательских файловых указателей:

class Archive {
    public:
        ...
        int extractData(string id, FILE *customOut, FILE *customErr);
        ...
};

int
Archive::extractData(string id, FILE *customOut, FILE *customErr)
{
    if (realExtractData(id.c_str(), customOut) != EXIT_SUCCESS) {
        fprintf(stderr, "something went wrong...\n");
        return EXIT_FAILURE;
    }
    return EXIT_SUCCESS;
}

Если я вызову вышеизложенное, как указано, нет задержки при выводе данных на стандартный вывод.Все извлеченные данные отправляются на стандартный вывод (stdout) почти сразу:

FILE *outFp = stdout;
FILE *errFp = stderr;
Archive *archive = new Archive(inFilename);

if (archive->extractData(id, outFp, errFp) != EXIT_SUCCESS) {
    fprintf(errFp, "[error] - could not extract %s\n", archive->getInFnCStr());
    return EXIT_FAILURE;
}

Если я изменю extractData(), чтобы его fprintf() вызов использовал customErr:

int
Archive::extractData(string id, FILE *customOut, FILE *customErr)
{
    if (realExtractData(id.c_str(), customOut) != EXIT_SUCCESS) {
        fprintf(customErr, "something went wrong...\n");  /* <-- changed this line */
        return EXIT_FAILURE;
    }
    return EXIT_SUCCESS;
}

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

Если я переключаю fprintf() обратно на использование stderr, а не customErr,все снова работает правильно, то есть , данные сразу сбрасываются на стандартный вывод (мой customOut).

Это проблема буферизации?Есть ли способ это исправить?

1 Ответ

0 голосов
/ 19 января 2012

"stderr а не customErr"

Стандартная ошибка не буферизована, что означает, что она распечатывается практически сразу.другие выходные потоки буферизуются, если вы не используете низкоуровневые вызовы ОС, что означает, что они будут печататься дольше, если вы не выполните очистку буфера чем-то вроде endl, :: flush или чем-то еще.

Если вы хотите выполнять низкоуровневые вызовы ОС и работаете с Unix, проверьте это:

http://www.annrich.com/cs590/notes/cs590_lecture_2.pdf

Я не прочитал все это, но насканируя его, он выглядит так, как будто он имеет информацию, аналогичную хорошей книге Стивенса по расширенному программированию в Unix, в которой подробно говорится об этом.

...