Си: проблема с getchar() и EOF(^Z) в Windows консоли
Уже очень долгое время пытаюсь понять:
Почему цикл не завершается, если я введу «dfkjsdf^Z», в то время как при
«dfkjsdf (тут я нажимаю Enter) ^Z» — завершается? То есть, как сделать так, чтобы он вышел из цикла, если я нажимаю CTRL+Z до того, как нажму Enter
Это, пожалуй, самое непонятное для меня в языке Си. И сколько бы я не рылся в гугле, ответа все же найти не смог..
1 ответ 1
Это не имеет никакого отношения к языку С, а зависит только от алгорима обработки комбинации Ctrl + Z консолью Windows и интерпретацией результатов этой обработки той реализацией стандартной библиотеки, которую вы используете.
Ввод в Windows терминале буферизуется построчно. При этом обработка присутствующих в буфере символов ^Z следует довольно запутанному алгоритму (по крайней мере при использовании стантартной библиотеки из комплекта MSVC).
Комбинация Ctrl + Z сама по себе не вызывает «проталкивания» накопленного буфера на выход (в отличие от комбинации Ctrl + D в Linux). Она лишь добавляет во входной буфер символ ^Z , т.е. \x1a . Вы можете нажать Ctrl + Z несколько раз, помещая во входной буфер несколько символов ^Z . После этого вы можете продолжать вводить что-то еще. Чтобы все-таки послать накопленный буфер ожидающему процессу, придется нажать Enter .
Если входной буфер содержит какие-то символы до первого появления символа ^Z , то ожидающий ввода процесс увидит все эти символы, после чего процесс увидит один символ ^Z , т.е. \x1a . Это будет просто символ \x1a . Никакой ситуации «конец файла» при этом не возникнет. Однако остаток входного буфера (после первого символа ^Z ) процессу виден не будет, как будто его и не было.
То есть если вы введете в Windows терминале последовательность abc^Z^Zdef^Zghi и нажмете Enter , то на вход ваш процесс получит символы a , b , c и \x1a . Весь остальной ввод пропадет бесследно. Заметьте, что при этом «пропадает» и символ перевода строки, cгенерированный нажатием Enter .
Если входной буфер сразу же начинается с символа ^Z , то входной буфер считается пустым. Все его содержимое пропадает, не происходит даже чтения символа ^Z . Возникает ситуация «конец файла».
То есть если вы введете в Windows терминале последовательность ^Zdef и нажмете Enter , то на вход ваш процесс не получит вообще ничего. Вместо этого функция ввода сообщит вам, что наткнулась на конец файла.
Поэтому для того, чтобы создать в буферизованном консольном вводе ситуацию «конец файла» придется вводить ^Z в самом начале новой строки.
Если вам нужна посимвольная обработка входа, то можно предварительно отключить построчную буферизацию ввода
В таком варианте каждый введенный символ будет немедленно читаться вашей getchar() и символ ^Z будет немедленно интерпретироваться как конец файла.
Источник
Функции getchar и putchar работают некорректно
Почему, когда нажимаешь Enter программа выводит результат? По идее программа должна выводить результат только когда нажмешь ctrl+z.
Win XP. Компилятор Miracle C. Может поставить Lunex и все будет работать отлично? Какую сборку тогда ставить? Можно ли совместно с XP?
Помощь в написании контрольных, курсовых и дипломных работ здесь.
Функции getchar и putchar — вывести количество символов в строке
Изучаю Си по книге кернигана ритчи. Подскажите почему эта прога отказывается выводить на экран.
Разобрать пример с Getchar и putchar
Помогите понять отличия результатов вывода сего кода: while((c = getchar()), c != EOF) < .
В чем суть функций putchar и getchar
подскажите кто знает что деляют эти функции
Для чего используется getchar и putchar?
Расскажите подробнее для чего используется getchar и putchar?
getchar работает правильно. Он берет один символ из stdin и возвращает его.
Добавлено через 28 секунд
И правильно Linux, а не Lunex
Может у него собственная компиляция, а ты ему замечание делаешь.
Добавлено через 1 минуту
я хакнул сервер Пентагона
Твоя проблема, крайне скудное количество имеющихся знаний о работе системы в целом. К примеру, есть у тебя машина, ты открываешь капот, достаешь первую попавшуюся деталюху, и делая вывод, основываясь на «то что бабки нашептали» , что эта деталь работает не верно, при этом не зная ни устройства автомобиля, ни для чего эта деталь нужна, ни внутренних механизмом взаимодействия и взаимовлияния этой деталюхи с другими подобного рода элементами машины.
Больше читай и все пройдет. «И даже грусть твоя, печаль, растает, словно утренний туман, под гнетом знаний» (C) вот я стихоплет
Как тогда вывести несколько строк сразу? Как только строка кончается, программа ее выдает.
Если бы я не EOF написал, а ‘\n’. Тогда понятно. Но я же EOF написал.
Getchar, как я понял, форумирует поток символов. Putchar выводит этот поток на экран. Enter ведь такойже сивол, как и другие.
Источник
Си, getchar() Изучаю самостоятельно Си, сейчас пытаюсь читать Кернигана и Ритчи (3-ье издание). Буксую конкретно
Как я понимаю, консоль в Си так устроена, что текст не передаётся в стандартный ввод программы, пока не нажмёшь клавишу Ввод. Ты можешь ввести сразу много символов и нажать Ввод: getchar вернёт эти символы один за другим, и ещё вернёт служебный символ «конец строки».
«-1» введённый с клавиатуры, это 2 символа: минус и единица. Не путай символы и их коды. Код символа ‘1’ равен 49, а не 1. Код -1 — это специальный код для обозначения конца файла. Символа с таким кодом быть не может. Ctrl+Z — это способ эмитировать «конец файла» при вводе в консоли.
Создай текстовый файл с входными данными и запускай программу так:
myApp1 3 года назад
Спасибо!
У меня тоже были мысли, что возмжно getchar() читает строку до нажатия Ввод. Но вот КУДА можно вернуть эти символы, не приложу ума. В массив?
Вот такая незаконченная программка получилась, два вопроса у меня.
1. можно ли в массив вернуть эти символы?
2. что тогда должно быть в правой части выражения ch[i] = .
Спасибо огромное.
#include
int main()
<
char ch[50] ;
int i;
while (( c= getchar())!= EOF)
<
for(i=0;i У меня тоже были мысли, что возмжно getchar() читает строку до нажатия Ввод Ничего он не читает, когда ввод нажимаешь программе передается введенный текст.
>ведет себя совсем не так, как следует из учебника.
Это ты не способен понимать прочитанное.
>ввести -1
Это два символа
>Что можно использовать как EOF для Windows?
Перенаправление потоков, EOF = конец файла.
Хорошая IDE для Си на винду это Pelles C.
Спасибо!
Pelles уже качаю и попробую, спасибо!
Буду использовать файлы в качестве потока ввода, даже как временная мера, чтоб не застревать на одном месте — полезно.
Но все равно хочу разобраться с вводом с клавиатуры.
Про то, что дело в том, что я торможу, а не в учебнике — понятно, просто были еще варианты, что может компилятор поменялся с тех пор, как книга Кернигана и Ритчи вышла, или что перевели коряво. значит, дело во мне, спасибо!
Источник
Getchar си не работает
| den140387 |
| ||
| Код |
| int main( void) < int c1, c2; |
/* Тут все правильно работает. getchar блокирует терминал и ждет ввода
* символа. Я ввожу ‘a’ и нажимаю */
c1 = getchar( );
/* Код символа ‘a’: c1 = 97 */
printf(«c1=%d\n», c1);
/* В этом месте не происходит блокировки терминала.
* В качестве c2 getchar воспринимает код клавиши , введенный ранее,
* то есть по сути код символа ‘\n’*/
c2 = getchar( );
/* с2 = 10 */
printf(«c2=%d\n», c2);
return 0;
>
Компиляция и запуск:
$ gcc-4.1.2 -Wall t.c
$ ./a.out
a
Я понимаю, почему так происходит. В качестве второго символа getchar воспринимает ранее введенный код клавиши
(символ ‘\n’, если я не ошибаюсь.)
А как сделать так, чтобы и при втором вводе getchar блокировал терминал и ожидал ввод нового символа?
Да, есть конечно решение в лоб:
| Код |
| c1 = getchar(); fflush( stdin); c2 = getchar(); |
| bsa |
| ||
Эксперт Профиль Репутация: 85
Это сообщение отредактировал(а) bsa — 16.1.2012, 13:28 | |||
| |
| xvr |
| ||
| |
| den140387 |
| ||
| Цитата |
| Есть еще вариант — удалять все из буфера ввода перед чтением: fflush(stdin); |
| Код |
| c1 = getchar(); fflush( stdin); c2 = getchar(); |
Вы не могли бы объяснить, что я неправильно сделал в этом коде?
Почему из буфер ввода не очищается перед вводом c2?
Это сообщение отредактировал(а) den140387 — 16.1.2012, 14:02
| bsa |
| ||
Эксперт Профиль Репутация: 85
| |||
| |
| den140387 |
| ||
| |
| bsa |
| |||
Эксперт Профиль Репутация: 85
Вывод ты сделал не верный. Поведение fflush() для файлов, отрытых на чтения, не определено. В некоторых системах (точнее, реализациях libc) может происходить очистка входного буфера. Добавлено через 42 секунды
| ||||
| |
| den140387 |
| ||||||||||
| Цитата |
| В некоторых системах (точнее, реализациях libc) может происходить очистка входного буфера. |
[ Время генерации скрипта: 0.1146 ] [ Использовано запросов: 21 ] [ GZIP включён ] Источник | |||||||||