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

58

Министерство образования Российской Федерации

РЯЗАНСКАЯ ГОСУДАРСТВЕННАЯ РАДИОТЕХНИЧЕСКАЯ АКАДЕМИЯ

ПРОГРАММИРОВАНИЕ НА ЯЗЫКЕ СИ

В СИСТЕМЕ ТУРБО–СИ

Методические указания к лабораторным работам № 8–15

Гр. 632-6311 выполнить работы 9 и 12

Рязань 2001 г.

Лабораторная работа № 8

ОБРАБОТКА ТЕКСТА С ИСПОЛЬЗОВАНИЕМ

ФУНКЦИЙ ВВОДА-ВЫВОДА ОДНОГО СИМВОЛА.

ПОБИТОВЫЕ ОПЕРАЦИИ. ПЕРЕКЛЮЧЕНИЕ ВВОДА-ВЫВОДА

Цель работы

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

Методические указания

1. Функция ввода-вывода одного символа

Для ввода одного символа, поступающего с терминала, используется функция getchar. Форма записи этой функции имеет такой вид:

getchar();

Она не имеет аргументов, получает поступающий символ с терминала и возвращает его значение программе.

Для вывода одного символа на экран дисплея используется функция putchar. Она имеет такой формат записи:

putchar (S);

S - это либо переменная типа char или int, либо константа этих типов.

Описание этих функций содержится в системном файле stdio.h.

Например, фрагмент программы

char ch; ch = getchar (); putchar (ch);

напечатает вводимый символ с клавиатуры на экран дисплея. Данный фрагмент программы, состоящий из двух операторов языка, можно упростить одним оператором putchar(getchar()).

Пример 1. Определить количество вводимых символов. Ввод символов закончить набором символа *.

# include <stdio.h>

# define STOP *

void main ( )

{ char ch; int k = 0;

while ((ch = getchar ())! = STOP) { k + +; putchar (ch);} printf("k=%d\n",k);

}

В этой программе цикл while будет выполняться до тех пор, пока не будет введен символ *. Следует отметить, что признак окончания ввода символа выбран не совсем удачно, потому что этот символ может быть неотъемлемой частью текста. Программист может выбрать любой другой признак окончания ввода текста, в том числе и символ "новая строка". В.этом случае нужно только изменить признак STOP на define STOP '\n'.

Однако при обработке текста, состоящего из нескольких строк, необходимо выбирать такой признак окончания ввода, который обычно не используется в тексте. Эта проблема была решена разработчиками вычислительных систем. Имеется специальный признак - конец файла, который обозначается EOF. Описание этого признака содержится в файле stdio.h. Одновременным нажатием клавиш [ctrl + z] вырабатывается признак EOF. Следовательно, с учетом признака EOF программа примера 1 может быть несколько упрощена, для чего нужно убрать директиву define и в операторе while STOP заменить на EOF.

2. Понятие буфера

Буфер – это специальная отводимая область памяти, являющаяся промежуточным хранилищем данных. Ввод данных с помощью функции getchar может быть буферизованным и небуферизованным. При небуферизованном вводе вводимые символы примера 1 будут сразу отражаться на экране оператором putchar. При буферизованном вводе, водимые символы собираются и помещаются в буфер, и программе они передаются либо после нажатия клавиши [Enter], либо когда будет обнаружен признак конца ввода.

Каждый из этих способов имеет свои достоинства и недостатки. Если при буферизованном вводе допущена ошибка при вводе символа, ее можно исправить. Но в диалоговых программах, когда требуется, чтобы каждая команда выполнялась при нажатии какой-либо клавиши, небуферизованный ввод окажется предпочтительным. Следовательно, при проектировании программ целесообразно учитывать эти обстоятельства. В языке Си имеются две функции ввода символов: getchar реализует буферизованный ввод; а функция getch – прямой.

3. Операции переключения ввода-вывода и работа с файлами

Операции переключения - это средства операционной системы MS-DOS, а не самого языка Си. С их помощью простую программу на языке Си можно превратить в инструмент для создания, чтения и копирования файлов. Существует два способа написания программ, работающих с файлами. Первый способ заключается в явном использовании специальных функций, которые открывают и закрывают файлы, организуют чтение и запись данных и выполняют множество других операций. Этот способ работы с файлами будет рассмотрен в лабораторной работе № 16. Второй способ состоит в том, чтобы программу, спроектированную первоначально в предположении, что данные вводятся в нее с клавиатуры и выводятся на экран, использовать таким образом, чтобы ввод и вывод осуществлялся из файла в файл. Для реализации этих функций необходимо прежде всего иметь откомпилированную, выполнимую программу.

а) Переключение ввода (создание файла)

Предположим, что программу примера 1 откомпилировали в выполнимую программу и записали в файл под именем priml. Допустим, что текст, вводимый с клавиатуры в программе priml, должен сохраниться в файле под именем TEXT. Для этого необходимо выполнить следующие действия:

1.Временно войти в DOS. Для этого нужно, перейти "в меню FILE и выбрать пункт этого меню OS Shell.

2.Ввести команду на выполнение программы \ DD \ priml > TEXT.,

где \ DD \ – имя каталога. Если priml находится в текущем .каталоге, то имя каталога можно опустить. Символ > служит обозначением операции переключения, в результате чего выходные данные программы priml будут направляться не на экран дисплея, а в файл ТЕХТ. В файл TEXT будут помещены все вводимые символы, а также число символов в тексте.

Для выхода из DOS и входа в турбо-среду следует набрать команду EXIT.

б) Переключение вывода (ввод данных в программу из файла). Для ввода данных в программу из файла следует выполнять те же действия, что и в пункте "а", за исключением того, что операцию переключения > надо заменить на операцию <. Естественно, для выполнения этой операции должен быть создан текстовый файл. Текстовый файл может быть создан либо с помощью пункта "а", либо с помощью любого текстового редактора, в том числе и редактора турбо-среды языка Си. Например, команда \ DD \ priml< TEXT приводит к тому, что содержимое файла TEXT будет исходными данными для программы priml. Результаты этой программы отражаются на экране дисплея. Используя данную операцию переключения, с помощью простой программы можно распечатать любой текстовый файл.

в) Комбинированное переключение (ввод-вывод). Комбинированное переключение позволяет направлять в программу ^ данные из одного файла, а результат записывать в другой файл, а также позволяет создать копии файлов. Например, команда \ DD \ prim1< ТНХТ > TEXT1 – указывает на то, что входные данные для prim1 содержатся в файле TEXT, а результаты выполнения этой программы запишутся в файл ТЕХТ1. Нельзя использовать в одной команде один и тот же файл и для ввода и для вывода одновременно.

4. Функции классификации символов

В языке имеются специальные функции для работы с символами. Если классифицируемый символ принадлежит к определенному классу, то функция возвращает ненулевое истинное значение и нуль (ложь) в противном случае. Эти функции описаны в файле math.h и приведены в табл. 1.

Имя функции

Назначение функции

isalpha (ch)

Определяет, является ли проверяемый символ ch буквой

isalnum (ch)

Буквой или цифрой

iscntrl (ch)

Управляющим символом или символом забоя, т.е. код меньше 32 или равен 127

isdigit (ch)

Является цифрой

isgrapg (ch)

Печатным, кроме пробела, 33<код<=126

islower (ch)

Строчной латинской буквой

isprint (ch)

Печатным; код = (от 32 126)

isupper (ch)

Прописной латинской буквой

Заметим, что перечисленные функции элементарно реализуются программистом. Например, функция isalpha (ch) может быть реализована следующим фрагментом: char ch; ((ch >= 'А' && ch <= 'Z') | | ( ch >= 'a' && ch <='z’)) ? 1:0.

5. Функции преобразования символов

Эти функции описаны в файле с именем ctype.h.

а) функция toupper (ch) - преобразует символ в верхний регистр;

б) функция tolower (ch) - преобразует символ в нижний регистр. Заметим, что коды строчных букв от прописных отличаются на величину 32 в десятичном представлении или на 40 и 20 соответственно в восьмеричном и шестнадцатеричном представлении. Таким образом, чтобы преобразовать заглавную букву в строчную, достаточно прибавить к коду символа величину 32, например ch + == 32.

6. Побитовые операции

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

а) операция поразрядного отрицания ~. Эта унарная операция изменяет 1 на 0 и наоборот. Например, ~5 == 2, потому что ~(101)2 = = (010)2;

б) поразрядное умножение &. Эта операция сравнивает последовательно разряд за разрядом два операнда. Для каждого разряда результат равен 1, если оба операнда равны 1, в противном случае 0. Так 5&2 = = 0, потому что (101)2&(010)2== (000)2;

в) поразрядовое сложение |. Эта операция сравнивает последовательно разряд за разрядом два операнда. Для каждого разряда результат равен 1, если любой из соответствующих разрядов операндов равен 1, в противном случае 0. Так 5|2= = 7, потому что (101)2 | (010)2-= (111)2;

г) исключающее или ^ Эта операция сравнивает последовательно разряд за разрядом два операнда. Результат равен 1, если оба операнда различны, в противном случае 0. Так 5 ^ 2 = = 7, потому что (101)2^010)2 ==(111)2.

Описанные операции часто используются для установки некоторых разрядов в нуль или единицу, причем другие разряды остаются неизменными. Так, например, z = z&2 установит все разряды z в 0 кроме первого. Первый – либо в нуль, либо в единицу в зависимости от значения z.

Аналогично оператор z = z|2 установит первый разряд в единицу и оставит все остальные разряды неизменными.

7. Операции сдвига

Операнды этих операций должны иметь тот же тип, что и побитовые операции и выполняться так же поразрядно. Эти операции сдвигают разряды влево и вправо.

а) Сдвиг влево «. Операция имеет вид:

<операнд> « число разрядов>.

Эта операция сдвигает разряды левого операнда влево на число позиций, указанное правым операндом.

Освобождающиеся позиции заполняются нулями, а разряды, сдвигаемые за левый предел левого операнда, теряются. Так, (101)2« ,2==,,= 10100, где каждый разряд сдвигается на две позиции.

б) Сдвиг вправо ». Операция имеет вид:

<операнд> <число позиций сдвига»

Эта операция сдвигает разряды левого операнда вправо на число позиций, указанное правым операндом. Разряды, сдвигаемые за правый предел левого операнда, теряются, а позиции, освобождающиеся слева, заполняются нулями. Так, 5 » 2 == = 1, потому что (101)2 » 2= = (001)2.

Приведем пример на использование побитовых операций.

Пример 2. Вывести на экран коды символов в двоичном представлении.

# include <stdio.h>

/* размер байта в битах*/

# define BYTE 8

void main ()

{ char ch; int i;

printf ("введите символы, ввод закончить <ctrl-z> \n");

while (( ch = getchar ())! = EOF)

putchar ('\n'); /* переход на новую строку */ printf("код символа %с =", ch);

/* цикл для печати одного символа */ ..,.,, for (i= BYTE; i > 0;i--) printf("%d",ch»i&l);

/* сдвигаются биты на i разрядов */

/* нулевой бит устанавливается либо В1, либо в 0 */

/* остальные биты равны нулю */ }

8.Пример выполнения задания

Определить в тексте число символов, число строк и число слов. Слова отделены друг от друга либо пробелами, либо символами новая строка и табуляция. Входные данные для программы находятся в текстовом файле ТЕХТ1. Результаты выполнения программы поместить в файл ТЕХТ2.

Для решения этой задачи, нижеследующую программу оттранслируем в выполняемую программу и запишем в файл под именем variant.

# include <stdio.h>

# define YES 1 /* признак, если символ часть слова */

# define NO 0 /* признак конца слова */

void main ()

{ char ch; /* вводимый символ */

int nc = 0; /* число символов */

int nl = 0; /* число строк */

int nw = 0; /* число слов */

int word = NO /* переменная, которая принимает значение */

/* либо конец, либо часть слова */

while ((ch = qetchar ())! = EOF)

{nc++; /* подсчет символов */

if (ch == ‘\n’) nl++;

if (ch  ==’ ‘&& ch! == ‘\n’ && ch! ==’ \t’&& word == NO)

{

word = YES /* начало нового слова */

nw++; /* подсчет слов */

}

if ((ch == ‘ ‘ ch == ‘ \n ‘ ch == ‘\t’)&& word == YES)

word = NO; /* достигнут конец слова */;

}

printf (“ число символов = % d \ n”, nc);

printf (“ число строк = % d \ n”, n1);

printf (“ число слов = % d \ n”, nw);

}

Команда переключения variant < TEXT1 > TEXT2 приведет к тому, что в файле TEXT2 будет записано число символов, строк и слов в тексте.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]