Я читал о 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);
нарочно.
Цель звонков 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 ++, который может быть синхронизирован с предоставленным дескриптором файла, не определено. На практике могут использоваться некоторые общие буферы, что объясняет то, что вы видите — по крайней мере, с вашим компилятором / библиотекой. Но такое поведение не гарантируется другими реализациями.
Мой первый вопрос «почему ты хочешь»? Eсть std::ostream::flush()
для этой цели, так что используйте, например, cout.flush();
,
Причина, по которой он «не работает», заключается в том, что буфер, fflush(FILE* f)
это не тот же буфер, который используется для std::ostream
(или по крайней мере это не гарантировано, что это будет). Вполне вероятно, что std::ostream::flush()
звонит fflush(FILE*)
на базовом объекте файла, который является частью реализации.