У меня возникла следующая проблема — необходимо перенаправить стандартный вывод в стандартный ввод напрямую, т.е. чтобы при использовании printf() инфу тут же можно было считать с помощью scanf() и т.д. Приложение под OpenGL без текстовых консолей. Пишу на VC++ ED.
Но смущает следующее. Во-первых, создается файл на диске. Во-вторых, по мере поступления инфы, файл разрастается... не смещать же указатель на начало файла после каждого printf()??
Вообще задача банальная — хочется иметь все вкусности printf(), при этом вывод производить на графическую консоль, либо в файл.
Пробовал также использовать dup2() — не помогло. Такое впечатление, что он вообще не работает...
Думаю еще про вариант сделать перегрузку стандартного printf(), но это все какие-то костыли.
Кто-нибудь знает более элегантный способ?
Заранее спасибо.
PS Хочется обойтись стандартным C без Win API, т.к. позже планирую переносить код под *nix.
Здравствуйте, 0xff, Вы писали:
0>Доброго времени суток,
0>У меня возникла следующая проблема — необходимо перенаправить стандартный вывод в стандартный ввод напрямую, т.е. чтобы при использовании printf() инфу тут же можно было считать с помощью scanf() и т.д. Приложение под OpenGL без текстовых консолей. Пишу на VC++ ED.
0>Единственный способ, который удалось найти 0>
0>Но смущает следующее. Во-первых, создается файл на диске. Во-вторых, по мере поступления инфы, файл разрастается... не смещать же указатель на начало файла после каждого printf()??
0>Вообще задача банальная — хочется иметь все вкусности printf(), при этом вывод производить на графическую консоль, либо в файл.
0>Пробовал также использовать dup2() — не помогло. Такое впечатление, что он вообще не работает...
0>Думаю еще про вариант сделать перегрузку стандартного printf(), но это все какие-то костыли.
0>Кто-нибудь знает более элегантный способ?
0>Заранее спасибо.
0>PS Хочется обойтись стандартным C без Win API, т.к. позже планирую переносить код под *nix.
Поищи на кл.слово pipe
Здравствуйте, 0xff, Вы писали:
0>Вообще задача банальная — хочется иметь все вкусности printf(), при этом вывод производить на графическую консоль, либо в файл.
Трубки (pipe) пробовал?
Хотя с ними тоже заморочек хватит. Придётся ведь как-то синхронизировать вывод в stdout (ну или в другой глобально доступный дескриптор файла) и чтение оттуда — вывод на экран. И в каком потоке это делать, тоже вопрос.
Ещё можно распотрошить структуру FILE и реализации тех же fputchar / fputs / fprintf, чтобы посмотреть, куда там вклиниться со своими магическими функциями.
Правда, это платформенно-зависимо.
Можно использовать строго iostream со специально обученным streambuf'ом. (Пример рукоделия — это hello debug window
Здравствуйте, Кодт, Вы писали:
К>Здравствуйте, 0xff, Вы писали:
0>>Вообще задача банальная — хочется иметь все вкусности printf(), при этом вывод производить на графическую консоль, либо в файл.
К>Трубки (pipe) пробовал? К>Хотя с ними тоже заморочек хватит. Придётся ведь как-то синхронизировать вывод в stdout (ну или в другой глобально доступный дескриптор файла) и чтение оттуда — вывод на экран. И в каком потоке это делать, тоже вопрос.
К>Ещё можно распотрошить структуру FILE и реализации тех же fputchar / fputs / fprintf, чтобы посмотреть, куда там вклиниться со своими магическими функциями. К>Правда, это платформенно-зависимо.
К>Можно использовать строго iostream со специально обученным streambuf'ом. (Пример рукоделия — это hello debug window
Все работает отлично, НО только в консольном приложении.
Если делать такое в приложении в котором консоль не была создана, то получается следующее недоразумение — fprintf(1,"bla-bla-bla\n") пишет инфу в пайп, а fprintf(stdout,"bla-bla-bla #2\n") — нет!
Решил проверить дескрипторы через _fileno(stdout), и что же получилось? А то что он равен -2
Лезу в хелп по слову _fileno, и вижу:
In Visual C++ 2005, there is a behavior change. If stdout or stderr is not associated with an output stream (for example, in a Windows application without a console window), the file descriptor returned is -2. In previous versions, the file descriptor returned was -1. This change allows applications to distinguish this condition from an error.
В общем, век живи, век RTFM... Получается, что с одной стороны stdout всегда есть и ссылается на дескриптор 1, а с другой стороны, только в случае если была создана консоль...
Короче говоря, теперь возник вопрос, как заново ассоциировать stdout и stdin с дескрипторами 1 и 0? Или единственный выход создавать консоль и прятать ее потом каким-то образом?
Здравствуйте, 0xff, Вы писали:
0>В общем, век живи, век RTFM... Получается, что с одной стороны stdout всегда есть и ссылается на дескриптор 1, а с другой стороны, только в случае если была создана консоль...
Получается, что с помощью _dup2(...,1),
— когда у тебя есть консоль (и stdout сидит на 1), ты его переназначаешь,
— а когда его нет — то ты создаёшь новый дескриптор.
Вот и вся история.
0>Короче говоря, теперь возник вопрос, как заново ассоциировать stdout и stdin с дескрипторами 1 и 0? Или единственный выход создавать консоль и прятать ее потом каким-то образом?
Было бы проще не заморачивать себе голову, а завести ещё один глобальный поток, и дублировать туда дескриптор либо трубки, либо стдаута.
Грубо говоря,
Здравствуйте, Кодт, Вы писали:
К>Здравствуйте, 0xff, Вы писали:
К>Было бы проще не заморачивать себе голову, а завести ещё один глобальный поток, и дублировать туда дескриптор либо трубки, либо стдаута. К>Грубо говоря, К>
Я для себя только что нашел более удобный способ. Можно переопределить stdin и stdout через freopen(), указав, какой-нибудь временный файл, а dup2() закроет его сам. Дескрипторы конечно будут не 0 и 1, но зато printf() будет работать без проблем. Единственное, что временный файл надо удалить будет потом. В общем, код теперь примерно такой