Getc, getchar, getche, getch взять байт из файла

В чем разница между getch() и getchar()?

Какая разница между getch и getchar ?

getchar() — стандартная функция, которая получает символ из stdin.

getch() является нестандартным. Он получает символ с клавиатуры (который может отличаться от stdin) и не отвечает на него.

Стандартная функция C — это getchar() , объявленная в . Он существовал в основном с самого начала. Она считывает один символ из стандартного ввода ( stdin ), который, как правило, пользователь клавиатуры, если только он не был перенаправлен (например, с помощью перенаправления ввода оболочки символа или трубы).

getch() и getche() являются старыми функциями MS-DOS, объявленными в и по-прежнему популярными в системах Windows. Они не являются стандартными функциями C; они не существуют во всех системах. getch считывает одно нажатие клавиши с клавиатуры, не дожидаясь, пока пользователь нажмет клавишу «Возврат», и не будет эхом нажатия клавиши. getche — это то же самое, за исключением того, что он выполняет эхо. Насколько я знаю, getch и getche всегда читаются с клавиатуры; они не зависят от перенаправления ввода.

Естественно возникает вопрос: если getchar — стандартная функция, как вы используете его для чтения одного символа, не дожидаясь ключа Return или без эха? И ответы на эти вопросы, по крайней мере, немного сложны. (На самом деле они достаточно сложны, и я подозреваю, что они объясняют постоянную популярность getch и getche , которые, если ничего другого не очень легко использовать.)

И ответ заключается в том, что getchar не имеет контроля над такими деталями, как эхо и буферизация ввода — насколько это касается C, это проблемы с более низким уровнем, зависящие от системы.

Но полезно понять базовую модель ввода, которую предполагает getchar . Смутно, обычно существует два разных уровня буферизации.

Когда пользователь набирает ключи на клавиатуре, они считываются драйвером терминала операционной системы. Как правило, в режиме по умолчанию драйвер терминала мгновенно выдает нажатия клавиш при их вводе (поэтому пользователь может видеть, что они набирают). Как правило, в режиме по умолчанию драйвер терминала также поддерживает некоторое редактирование строк — например, пользователь может нажать клавишу «Удалить» или «Назад», чтобы удалить случайно записанный символ. Чтобы поддерживать редактирование строк, драйвер терминала обычно собирает символы во входном буфере. Только когда пользователь нажимает Return, это содержимое этого буфера, доступное для вызывающей программы. (Этот уровень буферизации присутствует только в том случае, если стандартный ввод на самом деле является клавиатурой или другим последовательным устройством. Если стандартный ввод был перенаправлен на файл или канал, драйвер терминала не действует, и этот уровень буферизации не применяется.)

Пакет stdio считывает символы из операционной системы в свой собственный входной буфер. getchar просто извлекает следующий символ из этого буфера. Когда буфер пуст, пакет stdio пытается пополнить его, прочитав больше символов из операционной системы.

Итак, если мы проследим, что происходит, начиная с того, когда программа вызывает getchar в первый раз: stdio обнаруживает, что его входной буфер пуст, поэтому он пытается прочитать некоторые символы из операционной системы, но пока нет каких-либо символов, поэтому блокировки read . Между тем пользователь может вводить несколько символов, которые накапливаются в буфере ввода драйвера терминала, но пользователь еще не нажал Return. Наконец, пользователь нажимает Return, а заблокированный вызов read возвращается, возвращая целую строку символов в stdio , которая использует их для заполнения входного буфера, из которого она возвращает первый из них в этот начальный вызов getchar , который терпеливо ждал все это время. (И тогда, если программа вызывает getchar второй или третий раз, возможно, есть еще несколько символов — следующие символы в строке, введенной пользователем — доступный в буфере ввода stdio для возврата getchar немедленно., см. раздел 6.2 этих заметок курса C).

Но во всем этом, как вы можете видеть, getchar и пакет stdio не имеют контроля над такими деталями, как эхо или редактирование строк ввода, потому что они обрабатываются ранее на более низком уровне в драйвере терминала на шаге 1.

Таким образом, по крайней мере, в Unix-подобных операционных системах, если вы хотите прочитать символ, не дожидаясь ключа Return, или контролировать, являются ли символы эхом или нет, вы делаете это, настраивая поведение драйвера терминала. Детали меняются, но есть способ включить и выключить эхо и способ (на самом деле несколько способов) включить и отключить редактирование ввода строки. (По крайней мере, некоторые из этих деталей см. В этом вопросе SO или вопрос 19.1 в старом списке часто задаваемых вопросов.)

Когда редактирование строки ввода отключено, операционная система может немедленно возвращать символы (не дожидаясь клавиши Return), потому что в этом случае не нужно беспокоиться о том, что пользователь мог ввести неверное нажатие клавиши, которое должно быть «принято» назад «с помощью клавиши Delete или Backspace. (Но тем не менее, когда программа отключает редактирование строки ввода в драйвере терминала, если она хочет, чтобы пользователь исправлял ошибки, он должен реализовать свое собственное редактирование, потому что он увидит — то есть, последовательный вызовы getchar возвращаются — как неправильный символ пользователя, так и код символа для клавиши Delete или Backspace.)

Посимвольный ввод и вывод. Понятие буфера

Функции putchar() и getchar()

В заголовочном файле stdio.h содержится объявление не только функции printf() , но и многих других, связанных с вводом-выводом. Среди них есть функции, которые обрабатывают по одному символу за вызов — putchar() и getchar() .

Функция putchar() обычно принимает в качестве аргумента символ, либо символьную переменную и в результате своей работы выводит соответствующий символ на экран. Однако этой функции можно передать любое целое число, но, понятное дело, символа на экране вы можете не получить, если числу не соответствует ни один символ по таблице ASCII. Например:

Функции putchar() и printf() в определенном смысле взаимозаменяемы, т.к., используя ту или другую, можно получить один и тот же результат. Хотя программный код будет выглядеть по-разному:

В результате выполнения этого кода на экране будут напечатаны два слова «Hello», разделенные переходом на новую строку. С putchar() это выглядит несколько сложнее. Как мы знаем, любая строка оканчивается нулевым по таблице ASCII символом, в данном случае этот символ служит сигналом для прекращения вывода на экран. Но если бы понадобилось вывести на экран строку, разделяя ее символы каким-нибудь другим символом (например, тире), то и в случае с printf() было бы не так все просто:

Поэтому выбор в пользу той или иной функции зависит от ситуации и ваших предпочтений.

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

Если при выполнении этого кода ввести символ, то после нажатия Enter вы увидите два таких же символа на экране:

Первый — результат выполнения функции printf() , второй — putchar() . Если вы перед нажатием Enter введете несколько символов, то прочитан будет только первый, остальные будут проигнорированы. Посмотрите вот на этот код:

Как вы думает, как он будет выполняться? По идее после ввода символа, он должен сразу отображаться на экране функцией putchar() и запрашиваться следующий символ, потому что далее идет снова вызов getchar() . Если вы как корректный пользователь программы сначала введете первый символ и нажмете Enter, то символ отобразиться на экране. Потом вы введете второй символ и после Enter он тоже отобразиться. И тут программа завершится, не дав ввести вам третий символ.

Прежде чем попытаться найти объяснение, изобразим «некорректного пользователя» и перед первым нажатием Enter введем несколько символов (больше двух). После Enter вы увидите три первых символа введенной вами строки, и программа завершиться. Хотя куда логичней было бы ожидать, что будет прочитан только первый символ, потом выведен на экран и потом запрошен следующий символ.

Такое странное на первый взгляд поведение программы связано не с языком C, а с особенностью работы операционных систем, в которых реализован буферный ввод-вывод. При операциях ввода-вывода выделяется область временной памяти (буфер), куда и помещаются поступающие символы. Как только поступает специальный сигнал (например, переход на новую строку при нажатии Enter), данные из буфера передаются по месту своего назначения (на экран, в переменную и др.).

Теперь, зная это, давайте посмотрим, что происходило в нашей программе, и сначала разберем второй случай с «некорректным пользователем», т.к. для понимания этот случай проще. Когда пользователь ввел первый символ, он попал в переменную a, далее сработала функция putchar(a) и символ попал в буфер. Т.к. Enter’а не было, то содержимое буфера на экране не было отображено. Пользователь ввел второй символ, переменная b получила свое значение, а putchar(b) отправила это значение в буфер. Аналогично с третьим символом. Как только пользователь нажал Enter, содержимое буфера было выведено на экран. Но символы, которые были выведены на экран, были выведены не программой, а операционной системой. Программа же выводила символы еще до того, как мы нажали Enter.

Почему же в первом случае при выполнении программы мы смогли ввести и увидеть на экране только два символа? Когда был введен первый символ, то он был присвоен переменной a и далее выведен в буфер. Затем был нажат Enter. Это сигнал для выброса данных их буфера, но это еще и символ перехода на новую строку. Этот символ ‘\n’, наверное, и был благополучно записан в переменную b. Тогда в буфере должен оказаться переход на новую строку, после этого введенный символ (уже помещенный в переменную c). После нажатия Enter мы должны были бы увидеть переход на новую строку от символа ‘\n’ и букву. Однако печатается только буква. Причина этого вероятно в том, что переход на новую строку не хранится в буфере.

Во многих учебниках по языку C приводится пример считывания символов, вводимых пользователем, и их вывод на экран:

В переменной a всегда хранится последний введенный символ, но перед тем как присвоить a новое значение с помощью функции putchar() старое значение сбрасывается в буфер. Как только поступает символ новой строки, работа программы прекращается, а также, поскольку была нажата клавиша Enter, происходит вывод содержимого буфер на экран. Если в условии цикла while будет не символ ‘\n’, а какой-нибудь другой, то программа будет продолжать обрабатывать символы, даже после нажатия Enter. В результате чего мы можем вводить и выводить множество строк текста.

Илон Маск рекомендует:  max-width в CSS

Задание
Напишите программу посимвольного ввода-вывода, используя в качестве признака окончания ввода любой символ, кроме ‘\n’. Протестируйте ее.

При совместном использовании функций putchar() и getchar() обычно пользуются более коротким способом записи. Например:

Задание

  1. Объясните, почему сокращенный вариант записи посимвольного ввода-вывода работает правильно. Для этого опишите последовательность операций в условии цикла while .
  2. Перепишите вашу программу на более короткий вариант.

Как быть, если требуется «прочитать» с клавиатуры или файла неизвестный текст, в котором может быть абсолютно любой символ? Как сообщить программе, что ввод окончен, и при этом не использовать ни один из возможных символов?

В операционных системах и языках программирования вводят специальное значение, которое служит признаком окончания потока ввода или признаком конца файла. Называется это значение EOF (end of file), а его конкретное значение может быть разным, но чаще всего это число -1. EOF представляет собой константу, в программном коде обычно используется именно имя (идентификатор) константы, а не число -1. EOF определена в файле stdio.h.

В операционных системах GNU/Linux можно передать функции getchar() значение EOF, если нажать комбинацию клавиш Ctrl + D, в Windows – Ctrl + Z.

Задание
Исправьте вашу программу таким образом, чтобы считывание потока символов прерывалось признаком EOF.

Решение задач

Не смотря на свою кажущуюся примитивность, функции getchar() и putchar() часто используются, т.к. посимвольный анализ данных при вводе-выводе не такая уж редкая задача. Используя только функцию getchar() , можно получить массив символов (строку) и при этом отсеять ненужные символы. Вот пример помещения в строку только цифр из потока ввода, в котором может быть набран абсолютно любой символ:

Здесь ввод символов может прекратиться не только при поступлении значения EOF, но и в случае, если массив заполнен ( i ). В цикле while проверяется условие, что числовой код очередного символа принадлежит диапазону [48, 57]. Именно в этом диапазоне кодируются цифры (0-9). Если поступивший символ является символом-цифрой, то он помещается в массив по индексу i, далее i увеличивается на 1, указывая на следующий элемент массива. После завершения цикла к массиву символов добавляется нулевой символ, т.к. по условию задачи должна быть получена строка (именно для этого символа ранее резервируется одна ячейка массива – N-1 ).

Задание

  1. Напишите программу, которая считает количество введенных пользователем символов и строк.
  2. Напишите программу, которая подсчитывает количество слов в строке.

getch

Функция getch нужна для чтения одного символа с клавиатуры, этот символ на экран не выводится. Чаще всего данная функция используется чтобы не дать консоли преждевременно закрыться. Эта функция ожидает пока пользователь введёт символ и лишь затем закрывает консоль.

Чтобы воспользоваться функцией getch, необходимо подключить заголовочный файл:

Следует отметить, что данная функция не является стандартной! Данная функция является альтернативной формой команды getchar. Главной отличительной чертой является то, что вызывая getchar, консоль ожидает подтверждения ввода нажатием Enter. В случае с getch выход происходит сразу же, как только нажата какая-то клавиша. Возвращается код этой клавиши.

Для примера рассмотрим код с этой функцией:

Функция getch

выполняет ввод символа с клавиатуры без эхо- отображения на экране. В этой связи полезна для организации интерфейса с пользователем, при котором нажатие той или иной клавиши вызывает немедленную реакцию программы без отображения введенного символа на экране. Например, может использоваться в качестве задержки, пока не нажата любая клавиша.

Функция getche

выполняет небуферизуемый ввод символа с клавиатуры с эхо- отображением на экране. Перевод строки происходит при достижении правой вертикальной границы текущего активного окна.

Пример: программа иллюстрирует применение функций getch() и getche() для определения нажатий не только ASCII- клавиш, но и специальных клавиш.

Расширенный скэн-код: %#u\n»,ch);>

else printf(«Символьная клавиша %c\

Функции посимвольного потокового ввода

Функция fgetc

int fgetc(FILE *stream);

читает отдельный текущий символ из входного потока stream и увеличивает cсоответствующий указатель (если он есть) для указания следующего считываемого символа.

char string[] = «This is a test»;

stream = fopen(«DUMMY.FIL», «w+»);

fwrite(string, strlen(string), 1, stream);

fseek(stream, 0, SEEK_SET);

Функция getc

int getc(FILE *stream);

читает отдельный символ из текущей позиции потока stream и изменяет соответствующий указатель на файл для указания следующего символа.

printf(«Input a character:»);

printf(«The character input was: ‘%c’\n», ch);

Не нашли то, что искали? Воспользуйтесь поиском:

Лучшие изречения: Для студента самое главное не сдать экзамен, а вовремя вспомнить про него. 10035 — | 7499 — или читать все.

188.64.174.135 © studopedia.ru Не является автором материалов, которые размещены. Но предоставляет возможность бесплатного использования. Есть нарушение авторского права? Напишите нам | Обратная связь.

Отключите adBlock!
и обновите страницу (F5)

очень нужно

_getch, _getwch _getch, _getwch

Получает символ из консоли без отображения. Gets a character from the console without echo.

Этот API нельзя использовать в приложениях, выполняемых в среде выполнения Windows. This API cannot be used in applications that execute in the Windows Runtime. Дополнительные сведения: Функции CRT, которые не поддерживаются в приложениях универсальной платформы Windows. For more information, see CRT functions not supported in Universal Windows Platform apps.

Синтаксис Syntax

Возвращаемое значение Return Value

Возвращает считанный символ. Returns the character read. Ошибка не возвращается. There is no error return.

Примечания Remarks

Функции _getch и _getwch считывают один символ из консоли без вывода символа. The _getch and _getwch functions read a single character from the console without echoing the character. Эти функции нельзя использовать для считывания сочетания CTRL+C. None of these functions can be used to read CTRL+C. При считывании функциональной клавиши или клавиши со стрелкой каждая из этих функций должна вызываться дважды. Первый вызов возвращает 0 или 0xE0, а второй вызов возвращает фактический код клавиши. When reading a function key or an arrow key, each function must be called twice; the first call returns 0 or 0xE0, and the second call returns the actual key code.

Эти функции блокируют вызывающий поток, поэтому они потокобезопасны. These functions lock the calling thread and are therefore thread-safe. Описание неблокирующих версий см. в разделе _getch_nolock, _getwch_nolock. For non-locking versions, see _getch_nolock, _getwch_nolock.

Сопоставления подпрограмм обработки обычного текста Generic-Text Routine Mappings

Процедура Tchar.h Tchar.h routine _UNICODE и _MBCS не определены _UNICODE and _MBCS not defined _MBCS определено _MBCS defined _UNICODE определено _UNICODE defined
_gettch _gettch _getch _getch _getch _getch _getwch _getwch

Требования Requirements

Подпрограмма Routine Обязательный заголовок Required header
_getch _getch
_getwch _getwch или or

Дополнительные сведения о совместимости см. в разделе Совместимость. For more compatibility information, see Compatibility.

[C] Чтение файла с помощью fgetc

Навеяно тредом про Exim. Решил я проверить, действительно ли всё так хорошо и поток байт из файла можно читать с помощью fgetc(), а буферы винта и ФС сами разрулят ситуацию.

Для проверки использовался следующий код:

Каждый раз брался новый файл, чтобы оно не кэшировалось слишком.

Использовалось две ОС: 1) Mandriva Linux 2011.0, ext3, размер блока 4096 2) MS Windows XP, NTFS, размер блока 4096

Выводы делайте сами.

Во-первых, файл нужно брать один и тот же, просто сбрасывать кеш перед началом каждого последующего шага тестирования. Во-вторых, нужно учитывать фрагментацию.

Тем не менее, эти результаты явно не в пользу fgetc

А зачем файл читать посимвольно? Лучше же read’ом читать большими блоками, кратными размеру блока на диске.

> А зачем файл читать посимвольно? Лучше же read’ом читать большими блоками, кратными размеру блока на диске.

В этом и заключается моя позиция.

А что, кто-то рекомендует посимвольно? Покажите мне этих людей!

> кратными размеру блока на диске.

Самое забавное, что судя по моим таблицам эффективнее всего блоки, немного меньшие блока на диске. Это странновато, конечно.

А что, кто-то рекомендует посимвольно? Покажите мне этих людей!

В том самом треде, на который я дал ссылку в посте, есть два примера: yoghurt , Eshkin_kot .

Ну, например, при обработке CGI запросов (multipart/form-data) приходится искать ограничитель. И тут уж приходится придумывать, как скорость увеличить. Некоторые считывают входной поток посимвольно, параллельно со считыванием проверяя наличие разделителя. Мне проще скинуть все на жесткий диск (или даже сделать mmap), а потом читать построчно и вызывать strstr. Вот надо будет по скорости прикинуть, насколько этот способ медленнее посимвольного считывания.

Болезный, где ты в том треде увидел явный вызов fgetc?

receive_getc тут может указывать хоть на чёрта лысого.

Да и вообще в том топике речь шла о сети, не?

Я бы читал блоками в софтовый буфер, а из него брал посимвольно. Должно быть весьма шустро.

> Болезный, где ты в том треде увидел явный вызов fgetc?

Цитирую: «Функция receive_getc = fgetc(stdin)»

Ну и? Чем этот поток лучше потока из файла? Давай я сделаю cat file | тестилка , результат особо не поменяется.

Тем, что в своём примере ты юзаешь таки винт ещё, а на stdin данные могут поступать откуда угодно.

> Тем, что в своём примере ты юзаешь таки винт ещё, а на stdin данные могут поступать откуда угодно.

В предыдущем треде негласно считали, что это винт, ибо практически в каждом сообщении говорили про кэш винта.

Помимо кеша винта есть ещё сокбуфы, да и чего только нет.

> Помимо кеша винта есть ещё сокбуфы, да и чего только нет.

Я сейчас проверю cat /dev/zero | head -cX | тестилка . Мне уже стало интересно, как оно себя поведёт без винта.

> ибо практически в каждом сообщении говорили про кэш винта.

Я про кеш винта ничего не говорил :)

Помимо кеша винта есть ещё сокбуфы, да и чего только нет.

Вот, пожалуйста, без использования винта, только память:

Памяти более 2 ГБ свободно не было, а в своп лезть очень не хотелось, потому максимальный размер входного потока 2 ГБ. Тем не менее, fgetc всё равно показал свою неэффективность.

А если там гигабайтный файл? :)

> А если там гигабайтный файл? :)

Дак блоками же читаем. Памяти больше, чем размер блока, не съест.

вывод №1 TC не умеет писать тесты на производительность

вывод №2 TC не слишком разбирается с тем, что хочет померять

итог : некорректное сравнение по скорости кислого и мягкого

Так будет сложнее обрабатывать: что, если у вас начало строки с разделителем попадет на конец блока? Как вы его будете выделять, не считывая следующий блок?

> итог : некорректное сравнение по скорости кислого и мягкого

> Так будет сложнее обрабатывать: что, если у вас начало строки с разделителем попадет на конец блока? Как вы его будете выделять, не считывая следующий блок?

Это лишь вопрос реализации. Зато сам по себе такой метод работает быстрее.

А теперь добавь сюда логику, которая была в exim.

1) вы наверное думаете, что реализовали блочное чтение..

2) что fread и fgetc имеют исключительное отношение в ФС

3) что они алгоритмически применяются в одинаковых случаях и надо выбрать кто из них быстрее.

4) и что погрешности в секунды роли не играют

> и что погрешности в секунды роли не играют

Играют, но мне лень.

что они алгоритмически применяются в одинаковых случаях и надо выбрать кто из них быстрее.

Они могут применяться в одинаковых случаях.

что fread и fgetc имеют исключительное отношение в ФС

Это Вы себе придумали.

вы наверное думаете, что реализовали блочное чтение

А вот с этим спорить не буду, думаю.

>Тем не менее, fgetc всё равно показал свою неэффективность.

Это не неэффективность, это вполне объяснимая разница.

И fread, и fgetc лочат/разлочивают дескриптор на время работы. И та, и другая юзают один и тот же буфер при чтении. И та, и другая дочитывают в этот буфер, когда выходят за пределы. Просто fgetc вызывается на порядок больше раз.

При этом, как тут уже подметили, некоторые вещи можно быстро и удобно реализовать с fgetc, а не мудохаться с ручной буферизацией.

а не мудохаться с ручной буферизацией.

Можно просто написать оболочку. Что-нибудь вроде:

Это всё равно будет работать быстрее. По крайней мере с ФС.

> Это не неэффективность, это вполне объяснимая разница.

Нет уж, не передёргивайте, это неэффективность, вызванная вполне объяснимой разницей.

Судя по тестам windows победил.

Ну правильно. max_buf_size элементов, каждый по 1 байту. Да и вообще я не говорил «юзайте мою реализацию». Я говорил о самой идее.

Ты strace запускать пробовал?

> Судя по тестам windows победил.

Просто винты разные =)

И? Первый size — это размер типа данных, в байтах.

> Ты strace запускать пробовал?

Посмотреть что происходит, когда вызывается fgetc

> Посмотреть что происходит, когда вызывается fgetc

Да как бы пока что меня вполне устроили результаты тестирования и с blackbox. Но посмотрю.

Это лишь неэффективность чтения сырых данных. А как только понадобится посимвольный разбор данных, разница резко уменьшится.

Ок. Можешь добавить перед while строчку

setvbuf(f, buf,_IOFBF, n);

И померять еще раз

вы наверное думаете, что реализовали блочное чтение

А вот с этим спорить не буду, думаю.

напрасно..то что вы сделали может называться двойной буферизацией, в большинстве случаев излишней.

И вместо fgetc использовать getc.

> setvbuf(f, buf,_IOFBF, n); И померять еще раз

Не помогло. Скорость немного выросла, на пару МБ/сек.

> И вместо fgetc использовать getc.

Что-то толку всё равно нет, скорость не меняется.

позволю себе немного продолжить, а то newbie`сы ещё решат что надо все щели пихать fread и избегать fgetc и кол-во быдло кода резко возрастёт.

то что измеряет уважаемый TC реально зовётся кривой двойной буферизацией и ни разу не блочным чтением. На примере — если в приведённом коде, до тестов считать например 157 байт из файла (вполне жизненная ситуация — например чтение некоего заголовка), то замеры тестов с fgetc остануться в пределах погрешности измерений, а замеры заглушки через fread испортятся.

Вот таким вот простым движением TC получил метод с непредсказуемым поведением. Пытаясь это исправить придётся обращать внимание на выравнивание буферов памяти и блоков диска, а потом с удивлением увидеть что скорость теряется на переносе неких кусочков между вашим буфером и буфером FILE и что полученный код до удивления похож на код fread за отсутсвием обработки сигналов и ошибок, гибкости и переносимости.

Ёпрст. fread, fgetc прикладные библиотечные функции, скрывающие за собой детали реализации и взаимодействие с системой. Если надо получить байт из потока, то юзается fgetc, если заранее известное кол-во байт/структур/блоков то fread, если строка нужна — то fgets. Во всех них нормально сделана буферизация.

А если сцуко программист прикладник, которому показалось что 100500 вызовов fgetc стоит заменить тем же числом вызовов (зато своих)функций и 1-м fread, будет хреначить ворох кода, втащит системно-зависимые вещи, да ещё и дублируя функции стандартных библиотек, то он как минимум неграмотное @#$@.

В чем разница между getch () и getchar ()?

В чем точная разница между getch и getchar ?

4 ответа

getchar() — это стандартная функция, которая получает символ из стандартного ввода.

getch() является стандартным. Он получает символ с клавиатуры (который может отличаться от стандартного ввода) и не отображает его.

Стандартная функция C — это getchar() , объявленная в . Он существует в основном с незапамятных времен. Он читает один символ из стандартного ввода ( stdin ), который обычно является клавиатурой пользователя, если только он не был перенаправлен (например, через символ перенаправления ввода оболочки или канал).

getch() и getche() — это старые функции MS-DOS, объявленные в и до сих пор популярные в системах Windows. Они не являются стандартными функциями C; они существуют не во всех системах. getch считывает одно нажатие клавиши с клавиатуры немедленно, не дожидаясь, пока пользователь нажмет клавишу Return, и не повторяя нажатие клавиши. getche — то же самое, за исключением того, что он делает эхо. Насколько я знаю, getch и getche всегда читают с клавиатуры; на них не влияет перенаправление ввода.

Естественно возникает вопрос: если getchar — стандартная функция, как вы используете ее для чтения одного символа, не ожидая нажатия клавиши Return или не повторяя? И ответы на эти вопросы, по крайней мере, немного сложны. (На самом деле, они достаточно сложны, поэтому я подозреваю, что они объясняют непреходящую популярность getch и getche , которыми, если не getche ничего другого, очень легко пользоваться.)

И ответ заключается в том, что getchar не контролирует такие детали, как эхо и буферизация ввода — для C это проблемы низкого уровня, зависящие от системы.

Но полезно понять базовую модель ввода, которую принимает getchar . Заблуждение, как правило, существует два разных уровня буферизации.

Когда пользователь вводит клавиши на клавиатуре, они читаются драйвером терминала операционной системы. Как правило, в своем режиме по умолчанию драйвер терминала немедленно отображает нажатие клавиш при вводе (чтобы пользователь мог видеть, что он печатает). Как правило, в своем режиме по умолчанию драйвер терминала также поддерживает некоторую часть редактирования строки — например, пользователь может нажать клавишу Delete или Backspace, чтобы удалить случайно введенный символ. Для поддержки редактирования строки драйвер терминала обычно собирает символы во входном буфере . Только когда пользователь нажимает Return, содержимое этого буфера становится доступным для вызывающей программы. (Этот уровень буферизации присутствует, только если стандартный ввод фактически является клавиатурой или другим последовательным устройством. Если стандартный ввод был перенаправлен в файл или канал, драйвер терминала не действует, и этот уровень буферизации не применяется.)

Пакет stdio считывает символы из операционной системы в свой собственный входной буфер. getchar просто выбирает следующий символ из этого буфера. Когда буфер пуст, пакет stdio пытается заполнить его, читая больше символов из операционной системы.

Итак, если мы проследим, что происходит, когда программа впервые вызывает getchar : stdio обнаруживает, что его входной буфер пуст, поэтому он пытается прочитать некоторые символы из операционной системы, но пока нет доступных символов, поэтому блоки read вызова. Между тем, пользователь может набирать некоторые символы, которые накапливаются во входном буфере драйвера терминала, но пользователь еще не нажал Return. Наконец, пользователь нажимает кнопку Return, и заблокированный вызов read возвращается, возвращая в stdio целую строку символов, которая использует их для заполнения своего входного буфера, из которого он затем возвращает первый для этого начального вызова getchar , который все это время терпеливо ждал. (И затем, если программа вызывает getchar второй или третий раз, вероятно, есть еще несколько символов — следующие символы в строке, введенной пользователем), которые доступны во входном буфере stdio для немедленного возврата getchar . Подробнее об этом см. раздел 6.2 этих примечаний к курсу C. )

Но во всем этом, как вы можете видеть, getchar и пакет stdio не имеют никакого контроля над такими деталями, как эхо или редактирование строки ввода, потому что они обрабатываются ранее, на более низком уровне, в драйвере терминала, на шаге 1.

Таким образом, по крайней мере в Unix-подобных операционных системах, если вы хотите прочитать символ, не дожидаясь нажатия клавиши «Return», или контролировать, отображаются ли символы или нет, вы делаете это, регулируя поведение драйвера терминала. Детали могут быть разными, но есть способ включить и выключить эхо и способ (на самом деле несколько способов) включить и выключить редактирование строки ввода. (По крайней мере, для некоторых из этих деталей, смотрите этот вопрос SO или вопрос 19.1 в старом списке часто задаваемых вопросов по C ).

Когда редактирование строки ввода отключено, операционная система может немедленно возвращать символы (не дожидаясь нажатия клавиши «Return»), поскольку в этом случае не нужно беспокоиться о том, что пользователь мог набрать неправильное нажатие клавиши, которое необходимо «нажать». назад «с помощью клавиши Delete или Backspace. (Но по той же причине, когда программа отключает редактирование строки ввода в драйвере терминала, если она хочет позволить пользователю исправлять ошибки, она должна реализовать свое собственное редактирование, потому что она собирается видеть — то есть последовательно вызовы getchar будут возвращаться — как неправильный символ (ы) пользователя, так и код символа для клавиши Delete или Backspace.)

В чем разница между getch () и getchar ()?

В чем точная разница между getch и getchar ?

4 ответа

getchar() — это стандартная функция, которая получает символ из стандартного ввода.

getch() является стандартным. Он получает символ с клавиатуры (который может отличаться от стандартного ввода) и не отображает его.

Стандартная функция C — это getchar() , объявленная в . Он существует в основном с незапамятных времен. Он читает один символ из стандартного ввода ( stdin ), который обычно является клавиатурой пользователя, если только он не был перенаправлен (например, через символ перенаправления ввода оболочки или канал).

getch() и getche() — это старые функции MS-DOS, объявленные в и до сих пор популярные в системах Windows. Они не являются стандартными функциями C; они существуют не во всех системах. getch считывает одно нажатие клавиши с клавиатуры немедленно, не дожидаясь, пока пользователь нажмет клавишу Return, и не повторяя нажатие клавиши. getche — то же самое, за исключением того, что он делает эхо. Насколько я знаю, getch и getche всегда читают с клавиатуры; на них не влияет перенаправление ввода.

Естественно возникает вопрос: если getchar — стандартная функция, как вы используете ее для чтения одного символа, не ожидая нажатия клавиши Return или не повторяя? И ответы на эти вопросы, по крайней мере, немного сложны. (На самом деле, они достаточно сложны, поэтому я подозреваю, что они объясняют непреходящую популярность getch и getche , которыми, если не getche ничего другого, очень легко пользоваться.)

И ответ заключается в том, что getchar не контролирует такие детали, как эхо и буферизация ввода — для C это проблемы низкого уровня, зависящие от системы.

Но полезно понять базовую модель ввода, которую принимает getchar . Заблуждение, как правило, существует два разных уровня буферизации.

Когда пользователь вводит клавиши на клавиатуре, они читаются драйвером терминала операционной системы. Как правило, в своем режиме по умолчанию драйвер терминала немедленно отображает нажатие клавиш при вводе (чтобы пользователь мог видеть, что он печатает). Как правило, в своем режиме по умолчанию драйвер терминала также поддерживает некоторую часть редактирования строки — например, пользователь может нажать клавишу Delete или Backspace, чтобы удалить случайно введенный символ. Для поддержки редактирования строки драйвер терминала обычно собирает символы во входном буфере . Только когда пользователь нажимает Return, содержимое этого буфера становится доступным для вызывающей программы. (Этот уровень буферизации присутствует, только если стандартный ввод фактически является клавиатурой или другим последовательным устройством. Если стандартный ввод был перенаправлен в файл или канал, драйвер терминала не действует, и этот уровень буферизации не применяется.)

Пакет stdio считывает символы из операционной системы в свой собственный входной буфер. getchar просто выбирает следующий символ из этого буфера. Когда буфер пуст, пакет stdio пытается заполнить его, читая больше символов из операционной системы.

Итак, если мы проследим, что происходит, когда программа впервые вызывает getchar : stdio обнаруживает, что его входной буфер пуст, поэтому он пытается прочитать некоторые символы из операционной системы, но пока нет доступных символов, поэтому блоки read вызова. Между тем, пользователь может набирать некоторые символы, которые накапливаются во входном буфере драйвера терминала, но пользователь еще не нажал Return. Наконец, пользователь нажимает кнопку Return, и заблокированный вызов read возвращается, возвращая в stdio целую строку символов, которая использует их для заполнения своего входного буфера, из которого он затем возвращает первый для этого начального вызова getchar , который все это время терпеливо ждал. (И затем, если программа вызывает getchar второй или третий раз, вероятно, есть еще несколько символов — следующие символы в строке, введенной пользователем), которые доступны во входном буфере stdio для немедленного возврата getchar . Подробнее об этом см. раздел 6.2 этих примечаний к курсу C. )

Но во всем этом, как вы можете видеть, getchar и пакет stdio не имеют никакого контроля над такими деталями, как эхо или редактирование строки ввода, потому что они обрабатываются ранее, на более низком уровне, в драйвере терминала, на шаге 1.

Таким образом, по крайней мере в Unix-подобных операционных системах, если вы хотите прочитать символ, не дожидаясь нажатия клавиши «Return», или контролировать, отображаются ли символы или нет, вы делаете это, регулируя поведение драйвера терминала. Детали могут быть разными, но есть способ включить и выключить эхо и способ (на самом деле несколько способов) включить и выключить редактирование строки ввода. (По крайней мере, для некоторых из этих деталей, смотрите этот вопрос SO или вопрос 19.1 в старом списке часто задаваемых вопросов по C ).

Когда редактирование строки ввода отключено, операционная система может немедленно возвращать символы (не дожидаясь нажатия клавиши «Return»), поскольку в этом случае не нужно беспокоиться о том, что пользователь мог набрать неправильное нажатие клавиши, которое необходимо «нажать». назад «с помощью клавиши Delete или Backspace. (Но по той же причине, когда программа отключает редактирование строки ввода в драйвере терминала, если она хочет позволить пользователю исправлять ошибки, она должна реализовать свое собственное редактирование, потому что она собирается видеть — то есть последовательно вызовы getchar будут возвращаться — как неправильный символ (ы) пользователя, так и код символа для клавиши Delete или Backspace.)

лабы по информатике, егэ

лабораторные работы и задачи по программированию и информатике, егэ по информатике

Урок 1. Часть 3: Инструкции языка Си scanf, gets, getchar — ввод данных

Функция языка Си gets

Ввод данных — это предоставление компьютеру информации, необходимой для работы программы. Вводимая информация присваивается переменным и хранится в памяти компьютера. В программе переменная используется в операциях и выражениях.

Функция Си gets() помещает в переменную вводимую строку. В качестве параметра функции указывается имя переменной, в которую и помещается строка.

var name:string; begin writeln(‘введите имя’); readln(name); writeln(name); end.

Функция языка Си getchar

Функция Си getchar() запрашивает с клавиатуры единичный символ и практически для всех компиляторов безразлично, к какому типу (char или int) относится данный символ.

Вызов функции getchar осуществляется другим способом. Параметра у нее нет, но указать круглые пустые скобки после имени функции надо обязательно. Вызов происходит как присваивание какой-то переменной значения функции. Т.е. слева указывается переменная и ей присваивается значение функции, указанной справа.

Для сравнения выполним ту же задачу с функцией Си gets():

Функция языка Си scanf

Функция Си scanf () является более многогранной функцией, так как позволяет вводить в компьютер данные любых типов.

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

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

Указатели формата аналогичны тем, которые используются функцией printf.

Вопрос по io, c-standard-library, stdio, console-application, c &#8211 В чем разница между getch () и getchar ()?

Какова точная разница между getch а также getchar функции?

getchar() это стандартная функция, которая получает символ из стандартного ввода.

getch() это нестандартно. Он получает символ с клавиатуры (который может отличаться от стандартного ввода) и не отображает его.

getchar() заявлено в , Он существует в основном с незапамятных времен. Он читает один символ из стандартного ввода ( stdin ), которая обычно является клавиатурой пользователя, если она не была перенаправлена (например, с помощью символа перенаправления ввода оболочки) или труба).

getch() а также getche() старые функции MS-DOS, объявленные в и до сих пор популярны в системах Windows. Они не являются стандартными функциями C; они существуют не во всех системах. getch считывает одно нажатие клавиши с клавиатуры немедленно, не дожидаясь, пока пользователь нажмет клавишу «Return», и не повторяя нажатие клавиши. getche то же самое, за исключением того, что этоделает эхо. Насколько мне известно, getch а также getche всегда читать с клавиатуры; на них не влияет перенаправление ввода.

Естественно возникает вопрос, если getchar это стандартная функция, как вы используете ее для чтения одного символа, не дожидаясь нажатия клавиши «Return» или без эха? И ответы на эти вопросы, по крайней мере, немного сложны. (На самом деле, они достаточно сложны, так что я подозреваю, что они объясняют постоянную популярность getch а также getche , которые, если не что иное, очень просты в использовании.)

И ответ таков getchar не имеет никакого контроля над такими деталями, как эхо и буферизация ввода — с точки зрения C это проблемы нижнего уровня, зависящие от системы.

Но полезно понять базовую модель ввода, которая getchar предполагает. Смущает, как правило, естьдва разные уровни буферизации.

Когда пользователь вводит клавиши на клавиатуре, они читаются операционной системой.водитель терминала, Как правило, в своем режиме по умолчанию драйвер терминала немедленно отображает нажатие клавиш при вводе (чтобы пользователь мог видеть, что он печатает). Как правило, в своем режиме по умолчанию драйвер терминала также поддерживает некоторую часть редактирования строки — например, пользователь может нажать клавишу Delete или Backspace, чтобы удалить случайно набранный символ. Для поддержки редактирования строки драйвер терминала обычно собирает символы ввходной буфер, Только когда пользователь нажимает Return, содержимое этого буфера становится доступным для вызывающей программы. (Этот уровень буферизации присутствует, только если стандартный ввод фактически является клавиатурой или другим последовательным устройством. Если стандартный ввод был перенаправлен в файл или канал, драйвер терминала не действует, и этот уровень буферизации не применяется.)

Пакет stdio считывает символы из операционной системы в свой собственный входной буфер. getchar просто выбирает следующий символ из этого буфера. Когда буфер пуст, пакет stdio пытается заполнить его, читая больше символов из операционной системы.

Итак, если мы проследим, что происходит, когда программа вызывает getchar в первый раз: stdio обнаруживает, что его входной буфер пуст, поэтому он пытается прочитать некоторые символы из операционной системы, но пока нет доступных символов, поэтому read блоки вызова. Между тем, пользователь может набирать некоторые символы, которые накапливаются во входном буфере драйвера терминала, но пользователь еще не нажал Return. Наконец пользователь нажимает Return, и read возврат вызова, возвращая количество символов целой строки stdio , который использует их для заполнения своего входного буфера, из которого он затем возвращает первый для этого начального вызова getchar , который терпеливо ждал все это время. (А потом если программа вызывает getchar во второй или третий раз, там, вероятно,находятся еще несколько символов — следующие символы в строке, введенной пользователем — доступны во входном буфере stdio для getchar немедленно вернуться. Подробнее об этом смотритераздел 6.2 из этихС курс заметки.)

Но во всем этом, как вы можете видеть, getchar и пакет stdio не имеет контроля над такими деталями, как эхо или редактирование строки ввода, потому что они обрабатываются ранее, на более низком уровне, в драйвере терминала, на шаге 1.

Таким образом, по крайней мере в Unix-подобных операционных системах, если вы хотите прочитать символ, не дожидаясь нажатия клавиши Return, или контролировать, отображаются ли символы или нет, вы делаете это, регулируя поведение драйвера терминала. Детали могут быть разными, но есть способ включать и выключать эхо и способ (на самом деле несколько способов) включать и выключать редактирование строки ввода. (По крайней мере, некоторые из этих деталей см.этот ТАК вопрос, или жевопрос 19.1 в старомC FAQ список.)

Когда редактирование строки ввода отключено, операционная система может немедленно возвращать символы (не дожидаясь нажатия клавиши «Return»), поскольку в этом случае не нужно беспокоиться о том, что пользователь мог набрать неправильное нажатие клавиши, которое необходимо «нажать». назад «с помощью клавиши Delete или Backspace. (Но по той же причине, когда программа отключает редактирование строки ввода в драйвере терминала, если она хочет позволить пользователю исправлять ошибки, она должна реализовать свое собственное редактирование, потому что она будет видеть — то есть последовательно звонки в getchar собираются вернуться — оба пользователя неправильные символыа также код символа для клавиши Delete или Backspace.)

Илон Маск рекомендует:  Кеширование изображений с других сайтов
Понравилась статья? Поделиться с друзьями:
Кодинг, CSS и SQL