Язык Си в примерах/Верхний регистр
- Компиляция программ
- Простейшая программа «Hello World»
- Учимся складывать
- Максимум
- Таблица умножения
- ASCII-коды символов
- Верхний регистр
- Скобочки
- Факториал
- Степень числа
- Треугольник Паскаля
- Корень уравнения
- Система счисления
- Сортировка
- Библиотека complex
- Сортировка на основе qsort
- RPN-калькулятор
- RPN-калькулятор на Bison
- Простая грамматика
- Задача «Расчёт сопротивления схемы»
- Простая реализация конечного автомата
- Использование аргументов командной строки
- Чтение и печать без использования stdio
- Декодирование звукозаписи в формате ADX
- Другие примеры
- XCC C
- Дано
- текст — последовательность кодов ASCII — на стандартном вводе программы. Последовательность конечна, но ее длина заранее неизвестна.
- Надо
- вывести на стандартный вывод исходный текст, заменив в нем строчные буквы латиницы (a, …, z) прописными (A, …, Z).
- Указание
- воспользоваться особенностью кодовой таблицы ASCII: коды прописных букв отличаются от кодов соответствующих строчных на постоянную величину (а именно: 32.)
- Дополнительно
- предполагая поддержку средой русскоязычной локали, реализуйте аналогичное преобразование для кириллических текстов (используя стандартные функции языка.)
Решение
[править]В следующей программе введенный пользователем текст на латинице переводится в верхний регистр, то есть строчные буквы становятся заглавными. Все прочие коды — включая заглавные буквы и символы, не являющиеся латинскими буквами — не меняются.
Обратите внимание на то, что с символами (переменными типа char
)
можно оперировать как с числами. В частности, 'Z' - 'A'
есть число, равное
разности кодов символов A
и Z
, то есть (при использовании кодовой таблицы ASCII) 25 — число букв в латинском алфавите минус 1.
Символы можно также сравнивать друг с другом, при этом сравниваются их коды.
#include <assert.h>
#include <stdio.h>
int
main ()
{
int c;
while ((c = getchar ()) != EOF) {
if ('a' <= c && c <= 'z') {
c += 'A' - 'a';
}
putchar (c);
}
assert (! ferror (stdin));
return 0;
}
Главный цикл (и условие корректности ввода) этой программы почти полностью совпадают с рассмотренными в разделе ASCII коды символов. Однако, вместо использования printf
для вывода значений считанных кодов, здесь мы используем функцию putchar
для вывода самих кодов (знаков), возможно — после преобразования.[1] В коде по-прежнему используются функции getchar
и ferror
.[2][3]
Обратите внимание, что сформировать условие «конец потока» при вводе с клавиатуры можно вводом (в зависимости от системы и предполагая настройки по-умолчанию) Control-d или Control-z (также обозначаются C-d, ^D, C-z, ^Z.)
Использование стандартной библиотеки
[править]Приведенный выше код можно еще более упростить, если воспользоваться стандартной функцией преобразования регистра toupper
, объявленной в заголовке ctype.h
.[4]
Некоторые реализации языка, кроме того, определяют функции strlwr
и strupr
, которые переводят в нижний и верхний регистр строки, а не отдельные символы. Эти функции, однако, не являются стандартными и их наличие (или отсутствие) зависит от выбранной реализации языка.
#include <assert.h>
#include <ctype.h>
#include <stdio.h>
int
main ()
{
int c;
while ((c = getchar ()) != EOF) {
putchar (toupper (c));
}
assert (! ferror (stdin));
return 0;
}
Кроме латиницы
[править]Стандарт предусматривает также ряд средств для поддержки письменностей, отличных от «базовой» (26-символьной) латиницы. В основе такой поддержки — два следующих понятия:
- локаль — набор сведений о письменности, языке и культуре, включающий, помимо прочего, таблицы соответствия символов верхнего и нижнего регистров;
- широкие символьные типы (
wchar_t
,wint_t
; англ. wide character) — для представления ряда письменностей (например — основанных на иероглифах), а равно для представления текстов на нескольких языках, «байтового» типаchar
оказывается недостаточно; как следствие, в задачах, связанных с обработкой многоязычных текстов, его заменяет типwchar_t
; аналогично, в операциях ввода-вывода используется типwint_t
(и константаWEOF
.)
Соответственно, в исходный вариант вносятся следующие изменения.
- Появляется вызов
setlocale (LC_ALL, "")
, инициализирующий локаль в соответствии с текущими настройками. (По-умолчанию, при запуске программы полагаетсяsetlocale (LC_ALL, "C")
— установка «стандартной» локали.)[5] - Функции
getwchar
,towupper
,putwchar
заменяют соответствующие для «узких» символов (getchar
,toupper
,putchar
.) Соответственно меняются тип (int
→wint_t
) и константа признака исчерпания входного потока (EOF
→WEOF
.)[6][7][8] - Включаются соответствующие заголовки (
locale.h
,wchar.h
,wctype.h
.)
#include <assert.h>
#include <locale.h>
#include <stdio.h>
#include <wchar.h>
#include <wctype.h>
int
main ()
{
char *rl
= setlocale (LC_ALL, "");
assert (rl != 0);
wint_t c;
while ((c = getwchar ()) != WEOF) {
putwchar (towupper (c));
}
assert (! ferror (stdin));
return 0;
}
Отметим, впрочем, что принятые в конкретном языке правила обращения со строчными и заглавными могут оказаться сложнее простой зависимости символ—символ, предполагаемой в данном примере. Так, например, правила немецкого языка ставят в соответствие строчной «ß» пару заглавных — «SS» (например: Straße → STRASSE), что ни коим образом не может быть реализовано функцией towupper
.
Задания
[править]- Проверьте работу программы вводом строк
Hello!
иПривет!
. Удостоверьтесь, что «базовые» варианты решения выполняют заданное преобразование лишь для первой из них, в то время как «интернационализованное» решение действует и в отношении кириллического ввода. - Разработайте варианты программы, выполняющие (вновь для латиницы) a. преобразование верхнего регистра в нижний и b. «переключение» регистра —
Hello!
→hELLO!
. (Указание: воспользуйтесь стандартными функциямиislower
иisupper
.[9][10])
См. также
[править]Примечания
[править]- ↑ 7.21.7.8 The putchar function(англ.) WG14 N1570 Committee Draft. ISO/IEC (2011-04-12). Проверено 2012-11-19 г.
- ↑ 7.21.7.6 The getchar function(англ.) WG14 N1570 Committee Draft. ISO/IEC (2011-04-12). Проверено 2012-11-19 г.
- ↑ 7.21.10.3 The ferror function(англ.) WG14 N1570 Committee Draft. ISO/IEC (2011-04-12). Проверено 2012-11-19 г.
- ↑ 7.4.2 Character case mapping functions(англ.) WG14 N1570 Committee Draft. ISO/IEC (2011-04-12). Проверено 2012-11-19 г.
- ↑ 7.11.1.1 The setlocale function(англ.) WG14 N1570 Committee Draft. ISO/IEC (2011-04-12). Проверено 2012-11-19 г.
- ↑ 7.29.3.7 The getwchar function(англ.) WG14 N1570 Committee Draft. ISO/IEC (2011-04-12). Проверено 2012-11-19 г.
- ↑ 7.30.3.1.2 The towupper function(англ.) WG14 N1570 Committee Draft. ISO/IEC (2011-04-12). Проверено 2012-11-19 г.
- ↑ 7.29.3.9 The putwchar function(англ.) WG14 N1570 Committee Draft. ISO/IEC (2011-04-12). Проверено 2012-11-19 г.
- ↑ 7.4.1.7 The islower function(англ.) WG14 N1570 Committee Draft. ISO/IEC (2011-04-12). Проверено 2012-11-19 г.
- ↑ 7.4.1.11 The isupper function(англ.) WG14 N1570 Committee Draft. ISO/IEC (2011-04-12). Проверено 2012-11-19 г.