Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
12
Добавлен:
17.04.2015
Размер:
43.16 Кб
Скачать

7. Обработка сивольных данных.

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

Рассмотрим из них - putchar и getchar выполняющие ввод и вывод символа соответственно и создадим на их основе ряд своих полезных функций.

Рассмотрим примеры. Программа 1.вывводит на экран всепрописныелатин-скиебуквы. Мы уже напоминали что типы char и intвзаимозаменяемы.

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

Пример 1.

#include <stdio.h>

intmain()

{

char c;

c='A'

while(c<='Z')

{

putchar(c);

c=c+1;

}

}

Прежде, чем перейти к рассмотрению примеров, обсудим, как машина должна определять конец входного потока символов, вводимых с клавиатуры терминала. Можно, конечно, выбрать некоторый символ как признак конца потока, но нужна гарантия, что он нигде не повторится. В использованной нами операционной системе для получения такого символа надо нажать CTRL+Z. В программе значение этого символа мы будем использовать через символическое имя EOF(end of file). Теперь мы можем написать программы копирования файла(прмер 2.8) . Пока не обнаружен конец входного потока, ЭВМ получает с клавиатуры символ (это делает функция getchar) и сразу же выодит его на экран дисплея с помощью функции putchar. Для завершения программы достаточно нажать CTRL+Z.

Пример 2. /*ЭХО ПРОГРАММА*/

#include <stdio.h>

int main()

{

char c;

c=getchar();

while(c!=EOF)

{

putchar(c);

c=getchar();

}

}

Программу копирования можно написать и более компактно. В языке Си любое присваивание например, c=getchar(), можно использовать в любом выражении в качестве операнда; его значение - это просто значение, присваиваеое левой части. Учитывая сказанное, перепишем Эхо Программу . Это компактная, элегантная программа принимает символ с клавиатуры и присваивает его переменной с, а затем сравнивает его с признаком конца файла. Пока этот признак не обнаружен, выполняется тело цикла и символ выдается на экран. В противном случае цикл, а вместе с ним и вся программа завершаются.

Пример 3. *ЭХО ПРОГРАММА ВАР2.*/

#includestdio.h

int main()

{

char c; while((c=getchar())!=EOF)putchar(c);

}

Отметим, что включение присваиваний в проверки - сильноеединство языка, способствующее созданию программ. Учтите, что скобки вокруг присваивания внутри условия необходимы: приоритет операции != выше приоритета операции присваивания.

Скобки внутри условия, вокруг присваивания, необходимы. Приоритет != выше, чем приоритет =, из чего следует, что при отсутствии скобок проверка != будет выполняться до операции присваивания =. Таким образом, запись

c=getchar() !=EOF

эквивалентна записи

c= (getchar() !=EOF)

А это совсем не то, что нам нужно: переменной cбудет присваиваться 0 или 1 в зависимости от того, встретит или не встретитgetcharпризнак конца файла.

Подсчет символов

Следующая программа занимается подсчетом символов; она имеет много сходных черт с программой копирования.

#include<stdio.h>

/* подсчет вводимых символов; 1-я версия */

main()

{

long nc;

nc = 0;

while (getchar() != EOF)

++nc;

printf(“%ld\n”, nc);

}

Инструкция

++nc;

представляет новый оператор ++, который означает увеличить на единицу. Вместо этого можно было бы написать nc=nc+1, но ++ncнамного короче, а часто и эффективнее. Существует аналогичный оператор --, означающий уменьшить на единицу. Операторы ++ и -- могут быть как префиксными (++nc), так и постфиксными (nc++). Как будет показано в главе 2, эти две формы в выражениях имеют разные значения, но и ++nc, иnc++ добавляют кncединицу. В данном случае мы остановились на префиксной записи.

Программа подсчета символов накапливает сумму в переменной типа long. Целые типаlongимеют не менее 32 битов. Хотя на некоторых машинах типыintиlongимеют одинаковый размер, существуют, однако, машины, в которыхintзанимает 16 бит с максимально возможным значением 32767, а это - сравнительно маленькое число, и счетчик типаintможет переполниться. Спецификация %ldвprintfуказывает, что соответствующий аргумент имеет типlong.

Возможно охватить еще больший диапазон значений, если использовать тип double(т. е.floatс двойной точностью). Применим также инструкциюforвместоwhile, чтобы продемонстрировать другой способ написания цикла.

#include<stdio.h>

/* подсчет вводимых символов; 2-й версия */

main()

{

double nc;

for (nc = 0; getchar() != EOF; ++nc)

;

printf(“%.0f\n”, nc);

}

В printfспецификатор %fприменяется как дляfloat, так и дляdouble; спецификатор %.0fозначает печать без десятичной точки и дробной части (последняя в нашем случае отсутствует).

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

Наконец, заметим, что если ввод не содержит ни одного символа, то при первом же обращении к getcharусловие вwhileилиforне будет выполнено и программа выдаст нуль, что и будет правильным результатом. Это важно. Одно из привлекательных свойств цикловwhileиforсостоит в том, что условие проверяется до того, как выполняется тело цикла. Если ничего делать не надо, то ничего делаться и не будет, пусть даже тело цикла не выполнится ни разу. Программа должна вести себя корректно и при нулевом количестве вводимых символов. Само устройство цикловwhileиforдает дополнительную уверенность в правильном поведении программы в случае граничных условий.