Специальные функции ввода текстовых данных

Специальные функции ввода символьных данных getch() и getche() упрощают их набор (не приходится дополнительно нажимать клавишу Enter) и предоставляют дополнительные возможности. Ниже приводится программа и результат ее работы после нажатия на цифровую клавишу 5.

#include <stdio.h>

#include <conio.h>

void main()

{ char ch[4]={'1','2','3'};

ch[1]=getch();

printf("ch[0]=%c ch[1]=%c ch[2]=%c",ch[0],ch[1],ch[2]);

getch();

return;

}

//=== Результат работы ===

ch[0]=1 ch[2]=5 ch[3]=3

Функция getch (от get character – дай символ) организует ввод кода символа без эхо-сигнала, т.е. без отображения на экране знака, соответствующего нажатой клавише. Такая возможность может оказаться полезной при вводе секретных данных (пароль) или в ситуации, когда отображение символа нажатой клавиши может повредить текущее содержимое экрана. Очень часто эту функцию используют в качестве задержки работы программы до нажатия какой-либо клавиши.

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

Обе функции обращаются к буферу клавиатуры. Если к этому моменту буфер пуст, то происходит ожидание нажатия клавиши. Считанный символ из буфера клавиатуры выталкивается. Однако клавиши на клавиатуре разные. Большая их часть связана с отображаемыми символами – буквами, цифрами, знаками препинания и т.п. После их нажатия обращение к функциям getch/getche приводит к считыванию соответствующего кода
ASCII. В частности, к "отображаемым" клавишам относятся клавиши Esc (код 27), Enter (код 13), комбинация Ctrl+Z (код 26 – признак конца файла). Но на клавиатуре присутствует ряд клавиш, с которыми ассоциируются управляющие символы, не представленные в таблице ASCII. К ним, в частности, относятся функциональные клавиши F1, F2, …, стрелки управления курсором, клавиши Insert и Delete и др. От их нажатия в буфер клавиатуры поступает двухбайтовый код, содержащий в старшем байте 0, а в младшем байте так называемый scan-код (некий порядковый код, приписанный каждой клавише). В этом случае первое обращение к функциям getch/getche приводит к считыванию нулевого кода, а повторное обращение возвращает scan-код ранее нажатой клавиши. Таким образом, для анализа кода нажатой управляющей клавиши к функциям getch/getche приходится обращаться дважды (предварительно следует убедиться в том, что первое обращение возвратило 0).

Функция gets (от get string – дай строку) позволяет ввести в символьный массив текстовое значение, содержащее пробелы:

#include <stdio.h>

#include <conio.h>

void main()

{ char str[80];

gets(str);

printf("\nstr=%s",str);

getch();

}

При потоковом вводе со стандартного устройства stdin можно запросить заданное количество k символов, среди которых может встретиться и пробел:

cin.getline(str,k);

При этом можно ввести не более чем k-1 символ, т.к. нужно помнить о резервном байте для признака окончания строки. Если строка, набираемая пользователем, содержит более чем k-1 символ, то продолжение строки будет проигнорировано. И даже последующий оператор ввода не сможет им воспользоваться. Если строка ввода содержит меньше, чем k-1 символ, то она будет введена целиком. Более того, с помощью еще одного параметра, – символа завершения операции, можно досрочно прекратить ввод:

cin.getline(str,k,'Q');

Если в строке ввода будет досрочно обнаружен символ 'Q', то он уже не вводится.

Следует упомянуть еще одну функцию форматного ввода cscanf, ориентированную на работу с конкретным устройством – клавиатурой. Обращаются к ней точно так же как и к функции scanf, но они не дублируют друг друга. И вот почему. Дело в том, что стандартные устройства ввода (stdin) и вывода (stdout) могут быть подменены другими носителями информации (например, файлами или принтером). А ввод с клавиатуры и вывод на экран дисплея, образующих в совокупности консоль (пульт) оператора, переназначить нельзя.

Вывод текстовых данных

При выводе текстовых данных особые проблемы возникают только в том случае, когда сообщения, содержащие русские буквы, готовятся в среде Windows (кодовая страница 1251), а выводятся консольным приложением в 866-й кодовой странице. В этом случае можно написать сравнительно несложную функцию конвертирования текстов из одной кодировки в другую. В кодовой странице 1251 буквы русского алфавита кодируются подряд, начиная с кода 192 (большая буква 'А') до кода 255 (малая буква 'я'). Буквы 'Ё' и 'ё' имеют коды 164 и 184 соответственно. Поэтому при перекодировке необходимо:

· коды букв, принадлежащие интервалу [192, 239] уменьшить на 64, чтобы вогнать их в интервал [128, 174];

· коды букв, принадлежащие интервалу [240, 255] уменьшить на 16, чтобы вогнать их в интервал [224, 239];

· коды букв Ё и ё заменить на 240 и 241 соответственно.

#include <stdio.h>

#include <iostream.h>

#include <conio.h>

#include <string.h>

char *to_866(unsigned char *s)

{ static unsigned char str[80];

int j=0;

while (s[j]!='\0')

{ str[j]=s[j];

if(s[j]>=192 && s[j]<=239) str[j]-=64;

if(s[j]>=240 && s[j]<=255) str[j]-=16;

if(s[j]==164) str[j]=240;

if(s[j]==184) str[j]=241;

j++;

}

str[j]='\0';

return str;

}

void main()

{ char s[]="Привет;

cout << s << endl;

cout <<to_866(s) << endl;

getch();

}

//=== Результат работы ===

Специальные функции ввода текстовых данных - student2.ru

В первой строке вывод реализован без перекодировки, а во второй – с перекодировкой.

Форматный вывод

Для форматного вывода символьных значений в функции printf используется форматный указатель %c, а для вывода строк – форматный указатель %s. При создании консольных приложений Windows можно воспользоваться программой перекодировки, аналогичной функции to_866.

#include <stdio.h>

#include <conio.h>

void main()

{

char ch1='F';

unsigned char ch2='5';

char ch3[]="ABCD";

printf("%c %c %s",ch1,ch2,ch3);

getch();

}

//=== Результат работы ===

F 5 ABCD

Потоковый вывод

В потоковом выводе единственная проблема может возникнуть в связи с перекодировкой русских сообщений в консольном приложении Windows.

#include <iostream.h>

#include <conio.h>

void main()

{

char ch1='F';

unsigned char ch2='5';

char ch3[]="ABCD";

cout<<ch1<<' '<<ch2<<' '<<ch3;

getch();

}

//=== Результат работы ===

F 5 ABCD

Наши рекомендации