Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.22.249.158] |
|
Сообщ.
#1
,
|
|
|
Всем хай! Сходу к делу!
Как известно, функцией freopen можно переназначать потоки. Штука интересная вроде бы. Например, нужно считать данные из файла (а не с консоли), то делаем так, например: size_t records_count, i; const char* const name_file = "data.txt"; freopen( name_file, "r", stdin ); scanf( "%u", &records_count ); for ( i = 0; i < records_count; i++ ) { char buf[ 100 ]; gets_s( buf, 99 ); printf( "%s\n", buf ); } теперь, например, функция gets_s хватает данные из файлового потока, а не консольного и не нужно юзать функцию аля fgets, передавая хендлер на файл и пр. Но проблема в том, как вернуть ОБРАТНО к дефалту, чтобы снова стал stdin, не прибегая к ВИНАПИ?? Может есть какой-то очень простой однострочный способ( пробовал так, но все рухнуло и все... //freopen( NULL, "r", stdin ); подскажите как быть-то? |
Сообщ.
#2
,
|
|
|
Цитата FasterHarder @ Никак. freopen() предварительно закрывает поток, определяемый последним параметром, поэтому консольное устройство ввода (вывода), присоединённое к нему, более недоступно без повторного открытия. Но его можно просто открыть, пусть и fopen(). Проблема в том, что имена консольных устройств нестандартизированы, как ты верно заметил, так что без потери переносимости кода не напишешь.Но проблема в том, как вернуть ОБРАТНО к дефалту, чтобы снова стал stdin, не прибегая к ВИНАПИ?? Возможно, тебе изначально имело смысл предусмотреть возможность параметризации потока, из которого читать. Добавлено Но пришлось бы, увы, пожертвовать Цитата FasterHarder @ теперь, например, функция gets_s хватает данные из файлового потока, а не консольного и не нужно юзать функцию аля fgets, передавая хендлер на файл и пр. |
Сообщ.
#3
,
|
|
|
Qraizer, а вот смотри и поправь, плиз, если грубо ошибаюсь.
Вроде как языку Си доступны 5 потоков: stdin (ввода), stdout (вывода), stderr (ошибок) и еще каких-то 2 неизвестных, но они есть...) По дефалту потоки stdin/stdout привязаны к консоли/дисплею, т е вводим с клавы и выводим на экран. Чтобы переключить поток stdin на файл(дисковый текстовый) можно сделать freopen, указать путь до файла, режим открытия и САМ ПОТОК, т е stdin. А, например, если надо переключить поток ВЫВОДА stdout НА ПРИНТЕР, как быть??? У файлов есть путь (имя), а у принтера что?? Также, если пытаться переключиться, как ты говоришь через fopen обратно, то что указывать первым параметром (там путь char*), чтобы снова стал стандартный stdin с клавиатуры?? Т е я не оч.понимаю такой момент: у файлов ЕСТЬ имя + все эти функции fopen, freopen как раз-таки требуют указать 1ым параметром путь и файлы подходят идеально, а вот для принтера, клавиатуры, экрана нет ведь пути (хотя где-то видел "CON" для назначения стандартного stdout на экран ) поясни, плиз, эти моменты. Добавлено И все-таки странно, что можно переключить поток stdin с клавиатуры на файл, а обратно нельзя, хм...Неужели вся проблема в этом пути char*. Так-то ведь потоку все равно с чем работать "на том конце", будь-то файл, сканер, клавиатуры, трактор, океан и даже конфета, лишь оно имело соответствующий интерфейс...или я оч.грубо здесь ошибаюсь( |
Сообщ.
#4
,
|
|
|
Цитата FasterHarder @ Именно потому, что нет стандартных имён этих устройств, Стандарт обязывает библиотеки времени выполнения сделать необходимые действия перед main(), чтобы программа просто уже могла с ними работать, если надо.По дефалту потоки stdin/stdout привязаны к консоли/дисплею, т е вводим с клавы и выводим на экран. Цитата FasterHarder @ Стандарт не определяет никаких предоткрытых потоков для принтеров. В конце концов работа с принтерами кардинально различается для разных моделей, стандартизировать там просто нечего.А, например, если надо переключить поток ВЫВОДА stdout НА ПРИНТЕР, как быть??? У файлов есть путь (имя), а у принтера что?? Цитата FasterHarder @ Имя стандартного устройства ввода в твоей исполнительной среде.Также, если пытаться переключиться, как ты говоришь через fopen обратно, то что указывать первым параметром (там путь char*), чтобы снова стал стандартный stdin с клавиатуры?? Цитата FasterHarder @ Да. Представь себе какую-нибудь STMку в стиралке. Какое у неё будет стандартное устройство ввода? У тебя это кнопки, ручки и регуляторы, а как это связывается с потоками ввода в прошивке? А может их вообще нет? А может быть там есть какой-нибудь отладочный интерфейс через RS-232? Стандарт не может ничего диктовать подобным приложениям. Неужели вся проблема в этом пути char*. Добавлено Цитата FasterHarder @ В винде CON работает:... а вот для принтера, клавиатуры, экрана нет ведь пути (хотя где-то видел "CON" для назначения стандартного stdout на экран ) #include <stdio.h> void main( void ) { FILE* p = fopen("CON", "at"); fprintf(p, "Hello, world!\n"); fclose(p); } |
Сообщ.
#5
,
|
|
|
Qraizer, в целом так себе и представлял эти моменты с потоками, спс. за пояснения дополнительные!
В общем можно выработать такие правила: 1. Если в программе постоянно что-то вводится с клавиатуры и читается из файла, то не нужно ничего переназначать. Просто открывать все файлы через FILE*, fopen и все. 2. Если программа заточена исключительно на считывание данных из файла, то можно направить stdin на заданный файл, при необходимости перенаправить на др. и пр., но при этом про ввод с консоли стоит позабыть) В общем можно вообще никогда не использовать этот freopen и все будет нормально в прожке, просто иногда (п.2) удобнее направить на файл. То есть в целом этот freopen каких-то колоссальных преимуществ не дает, а лишь ИНОГДА помогает упростить код.. Qraizer, если в корне не согласен, то просьба пояснить. Добавлено для stdout есть "CON", неужели ничего нет для stdin(, как-то несправедливо) |
Сообщ.
#6
,
|
|
|
Цитата FasterHarder @ Почему это?для stdout есть "CON", неужели ничего нет для stdin(, как-то несправедливо) #include <stdio.h> void main( void ) { FILE *p = fopen("CON", "at"); FILE *q = fopen("CON", "rt"); char myName[16]; fprintf(p, "How are you? "); fflush(p); fscanf(q, " %15s", myName); fprintf(p, "Hello, %s!\n", myName); fclose(q); fclose(p); } |
Сообщ.
#7
,
|
|
|
Qraizer, спс за пояснения, тема достаточно интересная, но, как я понимаю, редко пригождается, поэтому эта тема на форуме будет мне служить подсказкой при необходимости, что да как
|