Язык Си в примерах/Верхний регистр: различия между версиями

Содержимое удалено Содержимое добавлено
Метка: possible spambot (testing)
Оформление, уточнения; примеры переписаны для посимвольного преобразования.
Строка 1:
{{{{Book template}}/Содержание «Язык Си в примерах»}}
 
; Дано: ''текст'' — последовательность кодов ASCII — на [[w:Стандартные потоки#Стандартный ввод |стандартном вводе]] программы. Последовательность конечна, но ее длина заранее неизвестна.
== Перевод символов в верхний регистр ==
; Надо: вывести на [[w:Стандартные потоки#Стандартный вывод |стандартный вывод]] исходный текст, заменив в нем строчные буквы латиницы (''a, …, z'') прописными (''A, …, Z'').
; Указание: воспользоваться особенностью [[w:ASCII#Кодировка |кодовой таблицы ASCII]]: коды прописных букв отличаются от кодов соответствующих строчных на постоянную величину (а именно: 32.)
 
== Решение ==
В следующей программе введенная пользователем строчка переводится в верхний регистр,
 
то есть маленькие буквы становятся заглавными.
В следующей программе введеннаявведенный пользователем строчкатекст на латинице переводится в верхний регистр,
Заглавные буквы и символы, не являющиеся латинскими буквами не меняются.
то есть маленькиестрочные буквы становятся заглавными.
ЗаглавныеВсе прочие коды — включая заглавные буквы и символы, не являющиеся латинскими буквами не меняются.
 
Обратите внимание на то, что с символами (переменными типа <code>char</code>)
можно оперировать как с числами. В частности, <source lang="c" enclose="none" >'Z' - 'A'</source> есть число, равное
разности ASCII кодов символов '<code >A'</code> и '<code >Z'</code>, то есть (при использовании кодовой таблицы ASCII) 25 &mdash; число букв в латинском алфавите минус  1.
Символы можно также сравнивать друг с другом, при этом сравниваются соответствующие им ASCIIих коды.
 
{{Якорь |upper.c}}
<source lang="c">
#include <stdioassert.h>
#include <stdio.h>
#define N 100
 
int main() {
int
char a[N];
main ()
int i;
{
scanf ("%s", a);
int ic;
for(i = 0; a[i] != '\0'; i++)
while if((c a[i] <= 'z'getchar &&()) a[i] >!= 'a'EOF) {
if ('a' <= c && c a[i] +<= 'Az') - 'a';{
printf ("%s\r\n", c += 'A' - 'a)';
return 0;}
putchar (c);
}
}
assert (! ferror (stdin));
 
return 0;
}
</source>
 
''Главный цикл'' этой программы напоминает таковой для рассмотренной в разделе [[../Максимум/]]. Однако, вместо использования <code >scanf</code> для чтения чисел — и, соответственно, <code >printf</code> для вывода результатов обработки — здесь мы используем функции <code >getchar</code> для чтения отдельных ''знаков'' (кодов) и <code >putchar</code> для вывода каждого «обработанного» знака.<ref name="getchar" /><ref name="putchar" />
При решении практических задач функцию перевода строчки в верхний регистр писать самому не надо. Это стандартная функция, которая есть в библиотеках различных языков программирования. В библиотеке <code>string</code> реализованы функции <code>strlwr</code> и <code>strupr</code>, которые переводят строчки
в нижний и в верхний регистр. Соответствующие функции для преобразования одного символа
<code>tolower</code> и <code>toupper</code> определены в библиотеке <code>ctype</code>.
<small>
==== Примечание ====
Приведённая выше программа содержит потенциальную уязвимость типа «[[:w:переполнение буфера|переполнение буфера]]».
</small>
 
Кроме того, меняется ''условие корректности'' ввода: если в предыдущей программе мы требовали возврата <code >EOF</code> как признака ''исчерпания'' входного потока, то <code >getchar</code> определена стандартом как возвращающая <code >EOF</code> также и как ''признак ошибки ввода.''<ref name="getchar" /> Поэтому, завершив чтение, мы явно требуем ''ложности'' значения функции ''признака ошибки'' <code >ferror</code> для стандартного ввода (<code >stdin</code>.)<ref name="ferror" />
Ниже приведена программа, которая использует функцию <code>tolower</code> библиотеки <code>ctype</code>
и переводит строчку в нижний регистр.
 
== Использование стандартной библиотеки ==
 
[[#upper.c |Приведенный выше]] код можно еще более упростить, если воспользоваться стандартной функцией преобразования регистра <code >toupper</code>, ''объявленной'' в заголовке <code >ctype.h</code>.<ref name="case-mapping" />
 
Некоторые ''реализации'' языка, кроме того, определяют функции <code >strlwr</code> и <code >strupr</code>, которые переводят в нижний и верхний регистр ''строки'', а не отдельные символы. Эти функции, однако, не являются ''стандартными'' и их наличие (или отсутствие) зависит от выбранной реализации языка.
 
{{Якорь |toupper.c}}
<source lang="c">
#include <stringassert.h>
#include <stdioctype.h>
#include <ctypestdio.h>
 
int main() {
int
int length, i;
main ()
char string[] = "ThIs Is A sTrInG";
{
length = strlen(string); /* Либо length = sizeof string - 1 */
int c;
for (i = 0; i < length; i++)
while ((c = getchar ()) != EOF) {
string[i] = tolower (string[i]);
printfputchar ("%s\n",toupper string(c));
}
return 0;
assert (! ferror (stdin));
}
 
return 0;
}
</source>
 
==См. также==
 
* [[Язык Си в примерах../ASCII коды символов/]]
* {{w |ASCII}}
 
== Примечания ==
{{Примечания | refs =
<!-- Пожалуйста поддерживайте алфавитный порядок для name. Спасибо. -->
<ref name="case-mapping" >{{Cite web | title = 7.4.2 Character case mapping functions | url = http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf#page=221 | work = WG14 N1570 Committee Draft | publisher = ISO/IEC | datepublished = 2011-04-12 | lang = en | accessdate = 2012-11-19}}</ref>
<ref name="ferror" >{{Cite web | title = 7.21.10.3 The ferror function | url = http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf#page=357 | work = WG14 N1570 Committee Draft | publisher = ISO/IEC | datepublished = 2011-04-12 | lang = en | accessdate = 2012-11-19}}</ref>
<ref name="getchar" >{{Cite web | title = 7.21.7.6 The getchar function | url = http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf#page=350 | work = WG14 N1570 Committee Draft | publisher = ISO/IEC | datepublished = 2011-04-12 | lang = en | accessdate = 2012-11-19}}</ref>
<ref name="putchar" >{{Cite web | title = 7.21.7.8 The putchar function | url = http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf#page=351 | work = WG14 N1570 Committee Draft | publisher = ISO/IEC | datepublished = 2011-04-12 | lang = en | accessdate = 2012-11-19}}</ref>
}}
 
{{BookCat}}