В чем разница между getch () и getchar ()? - PullRequest
17 голосов
/ 07 февраля 2012

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

Ответы [ 4 ]

28 голосов
/ 07 февраля 2012

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

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

3 голосов
/ 04 июля 2018

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

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

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

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

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

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

  2. Пакет 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 FAQ .)

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

1 голос
/ 06 октября 2013

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

getchar() он получает ввод и отображает его на экране, когда мынажмите клавишу ввода.

0 голосов
/ 04 июля 2018
  • getchar - это стандартный C, найденный в stdio.h.Он читает один символ из stdin (стандартный поток ввода = консольный ввод в большинстве систем).Это блокирующий вызов, поскольку он требует, чтобы пользователь набрал символ, а затем нажмите клавишу ввода.Он отображает пользовательский ввод на экран.

  • getc(stdin) эквивалентен на 100% getchar, за исключением того, что он также может использоваться для других входных потоков.

  • getch является нестандартным, обычно встречается в старом устаревшем заголовке MS DOS conio.h.Он работает так же, как getchar, за исключением того, что он не блокируется после первого нажатия клавиши, он позволяет программе продолжаться без нажатия клавиши ввода.Он не отображает ввод на экран.

  • getche такой же, как getch, также нестандартный, но он отображает ввод на экран.

...