Почему fflush (stdout) не работает с iostream?

Я читал о freopen() и понял, что если мы укажем ему stdin / stdout, функция будет работать, даже если мы закодируем с помощью cin / cout.

Изучив немного, я нашел эту ссылку freopen () эквивалент для потоков C ++, где один из пользователей ответил:

Из стандарта C ++ 27.3.1:
«Предмет cin управляет вводом из буфера потока, связанного с объектом stdinзаявлено в <cstdio>«.

Так что согласно стандарту, если мы перенаправим stdin это также перенаправит cin, Наоборот для cout,

Также увидел что-то похожее на CPPReference:
http://en.cppreference.com/w/cpp/io/cin
http://en.cppreference.com/w/cpp/io/cout

Глобальные объекты std :: cout и std :: wcout управляют выводом в потоковый буфер определенного типа реализации (производный от std :: streambuf), связанный со стандартным выходным потоком C stdout.

Вот где это немного запутало, так как я также читал о сбросах и заметил, что fflush (stdout) просто не будет работать с cin / cout.

Например, этот пример кода ничего не печатает:

#include <cstdio>
#include <iostream>

using namespace std;

int main() {
ios::sync_with_stdio(false);
cin.tie(0);

int n;
cout << "Please, enter a number: \n";
fflush(stdout);
cin >> n;
}

Пока этот код будет напечатан в output.txt:

#include <cstdio>
#include <iostream>

using namespace std;

int main() {
ios::sync_with_stdio(false);
cin.tie(0);

freopen("output.txt", "w", stdout);

cout << "Some string";
while (true);
}

Удаление ios::sync_with_stdio(false); из первого примера кода, он ведет себя как ожидалось. А также freopen() работает в любом случае (с этим или без него).

Итак, вопрос: почему fflush (stdout) не работает с iostream, а freopen (…, stdout) работает? Может быть, этот вопрос может стать еще глубже: с каким расширением ассоциируется cin / cout со stdin / stdout?

Простите за длинный пост. Я старался быть максимально подробным и лаконичным.

Надеюсь это понятно.

Заранее спасибо.

П.С .: Я положил ios::sync_with_stdio(false); а также cin.tie(0); нарочно.

2

Решение

Цель звонков ios::sync_with_stdio(false) а также cin.tie(0) то, что вы поместили в «специально», должно гарантировать (1), что потоки ввода / вывода C (stdoutи т. д.) не синхронизируются со своими аналогами в C ++ (std::coutи т. д.) и (2) обеспечить stdout а также stdin не связаны (т. е. чтение из stdin не обязательно вызывает stdout быть покрасневшим).

Поэтому fflush(stdout) не влияет std::cout в вашем примере. Вы специально отключили такой эффект, и оба могут быть буферизованы отдельно.

Эффект freopen() в любом потоке C ++, который может быть синхронизирован с предоставленным дескриптором файла, не определено. На практике могут использоваться некоторые общие буферы, что объясняет то, что вы видите — по крайней мере, с вашим компилятором / библиотекой. Но такое поведение не гарантируется другими реализациями.

4

Другие решения

Мой первый вопрос «почему ты хочешь»? Eсть std::ostream::flush() для этой цели, так что используйте, например, cout.flush();,

Причина, по которой он «не работает», заключается в том, что буфер, fflush(FILE* f) это не тот же буфер, который используется для std::ostream (или по крайней мере это не гарантировано, что это будет). Вполне вероятно, что std::ostream::flush() звонит fflush(FILE*) на базовом объекте файла, который является частью реализации.

3

По вопросам рекламы [email protected]