Getchar си не работает

Си: проблема с 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 — это способ эмитировать «конец файла» при вводе в консоли.

Читайте также:  Не работает история местоположений google

Создай текстовый файл с входными данными и запускай программу так:
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 си не работает

Профиль
Группа: Участник
Сообщений: 9
Регистрация: 21.12.2011

Репутация: нет
Всего: нет

Добрый день!
Возникла проблема при использовании функции getchar.
Хочу с клавиатуры ввести 2 символа, но getchar считывает только один, а в качестве второго пишет код ‘\n’

den140387
Дата 16.1.2012, 13:12 (ссылка) | (нет голосов) Загрузка .
Код
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
Дата 16.1.2012, 13:26 (ссылка) | (нет голосов) Загрузка .

Эксперт

Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 85
Всего: 196

Код
int main( void)
<
int c1, c2;
scanf(» %c», &c1);
printf(«c1=%d\n», c1);
scanf(» %c», &c2); //пробел перед %c обязателен.
printf(«c2=%d\n», c2);
return 0;
>

Это сообщение отредактировал(а) bsa — 16.1.2012, 13:28

Эксперт

Профиль
Группа: Комодератор
Сообщений: 7040
Регистрация: 28.8.2007
Где: Химки, Московская обл

Репутация: 35
Всего: 223

Еще можно заставить не ждать нажатия Enter (т.е. перевести терминал в так называемый raw режим), но это делается системно зависимыми средствами.
Есть еще вариант — удалять все из буфера ввода перед чтением: fflush(stdin);

xvr
Дата 16.1.2012, 13:46 (ссылка) | (нет голосов) Загрузка .

Профиль
Группа: Участник
Сообщений: 9
Регистрация: 21.12.2011

Репутация: нет
Всего: нет

den140387
Дата 16.1.2012, 14:01 (ссылка) | (нет голосов) Загрузка .
Цитата
Есть еще вариант — удалять все из буфера ввода перед чтением: fflush(stdin);
Код
c1 = getchar();
fflush( stdin);
c2 = getchar();

Вы не могли бы объяснить, что я неправильно сделал в этом коде?
Почему из буфер ввода не очищается перед вводом c2?

Это сообщение отредактировал(а) den140387 — 16.1.2012, 14:02

bsa
Дата 16.1.2012, 14:12 (ссылка) | (нет голосов) Загрузка .

Эксперт

Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 85
Всего: 196

Цитата(http://www.cplusplus.com/reference/clibrary/cstdio/fflush/)
If it was open for reading and the last operation was an input operation, the behavior depends on the specific library implementation. In some implementations this causes the input buffer to be cleared, but this is not standard behavior.

Профиль
Группа: Участник
Сообщений: 9
Регистрация: 21.12.2011

Репутация: нет
Всего: нет

den140387
Дата 16.1.2012, 14:14 (ссылка) | (нет голосов) Загрузка .
bsa
Дата 16.1.2012, 14:20 (ссылка) | (нет голосов) Загрузка .

Эксперт

Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 85
Всего: 196

Цитата(den140387 @ 16.1.2012, 15:14 )
Теперь понятно, что fflush не всегда очищает входной буфер.

Вывод ты сделал не верный. Поведение fflush() для файлов, отрытых на чтения, не определено. В некоторых системах (точнее, реализациях libc) может происходить очистка входного буфера.

Добавлено через 42 секунды

M
bsa
den140387, если ответ на вопрос получен, то пометь тему решенной

Профиль
Группа: Участник
Сообщений: 9
Регистрация: 21.12.2011

Репутация: нет
Всего: нет

den140387
Дата 16.1.2012, 14:22 (ссылка) | (нет голосов) Загрузка .
Цитата
В некоторых системах (точнее, реализациях libc) может происходить очистка входного буфера.

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • FAQ раздела лежит здесь!

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

Правила форума «C/C++: Для новичков»
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »

[ Время генерации скрипта: 0.1146 ] [ Использовано запросов: 21 ] [ GZIP включён ]

Источник

Оцените статью