Чтение онлайн

ЖАНРЫ

Язык Си - руководство для начинающих

Д. МАРТИН

Шрифт:

Теперь вернемся к нашей программе и попробуем ее выполнить. Если в вашей системе реализован небуферизованный ввод, результат может выглядеть, например, следующим образом:

ИИннттеерреесснноо ppаaббooттaаеeтт ллии ооннаа . Думаю что да.

При вводе все символы вплоть до признака STOP (звездочка), медленно отображаются на экране (эхо-печать). Дублируются даже пробелы. Однако, как только вы ввели признак STOP, работа программы прекращается и все, что вы набираете на пульте после этого, появляется на экране без эхо-дублирования.

Теперь посмотрим, что будет происходить в системе, обладающей буферизованным вводом. В этом случае программа не

начнет работать до тех пор, пока вы не нажмете на клавишу [ввод]. Вот пример возможного диалога

Интересно, работает ли она. Гм , не знаю [ввод].

Интересно, работает ли она.

Первая строка была целиком передана программе. Программа последовательно читает эту строку по одному символу и также по одному символу выводит на печать до тех пор, пока не встретит символ *.

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

 /* подсчет символов! */

#define STOP *

main

{

char ch;

int count =0; /* инициализация счетчика символов 0 */

while ((ch = getchar)!= STOP)

 {

putchar (ch);

count++; /* прибавить 1 к счетчику */

}

printf (" \n Всего было прочитано %d символов \n ' , count);

 }

Чтение одной строки

Давайте подумаем, какие дополнительные усовершенствования можно ввести в программу, используя только те средства, которыми мы владеем. Первое, что легко можно сделать - это заменить признак окончания ввода данных. Но можно ли предложить что-то лучшее, чем символ *? Одной из возможностей является использование символа "нова строка" (\n). Для этого нужно лишь переопределить признак STOP.

#define STOP ' \n '

Какой это даст эффект? Очень большой ведь символ "новая стрoка" пересылается при нажатии клавиши [ввод], следовательно, в результате наша программа будет обрабатывать одну вводимую строку. Предположим, например, что мы внесли указанное изменение в программу подсчет символов1, а затем при ее выполнении ввели следующую строку:

О! Быть сейчас во Фресно, когда здесь лето, [ввод]

В ответ на экране появятся следующие строки

О! Быть сейчас во Фресно, когда здесь лeтo, Всего бьпо прсчитано 43 симвoлa

(Если бы мы не включили в управляющую строку оператора printf в качестве первого символа признак \n, второе сообщение появилось бы справа от запятой, после слова лето. Мы предпочли избежать такого склеивания строк).

Признак, появляющийся в результате нажатия клавиши [ввод] не входит в число символов (43), подсчитанных программой, поскольку подсчет осуществляется внутри цикла.

Чтение одиночного файла

Каким может быть идеальный признак STOP? Это должен быть такой символ, который обычно не используется в тексте и следовательно, не приводит к ситуации, когда он случайно встретится при вводе, и работа программы будет остановлена раньше чем мы хотели бы.

Проблема подобного сорта не нова, и, к счастью для нас, она уже была успешно решена проектировщиками вычислительных систем. На самом деле задача, которую они рассматривали, была не сколько отличной от нашей, но мы вполне можем воспользоваться их решением. Занимавшая их проблема касалась "файлов". Файлом можно назвать участок памяти, в который помещена некоторая информация. Обычно файл хранится в некоторой долговременной памяти,

например на гибких или жестких дисках или на магнитной ленте. Чтобы отмечать, где кончается один файл и начинается другой, полезно иметь специальный символ, указывающий на конец файла. Это должен быть символ, который не может появиться где-нибудь в середине файла, точно так же как выше нам требовался символ, обычно не встречающийся во вводимом тексте. Решением указанной проблемы служит введение специального признака, называемого "End-of-File" (конец файла), или EOF, для краткости. Выбор конкретного признака EOF зависит от типа системы он может состоять даже из нескольких символов. Но такой признак всегда существует, и компилятор с языка Си, которым вы пользуетесь, конечно же "знает", как такой признак действует в вашей системе.

РИС. 6.4. Структура текстового файла с признаком EOF

Каким образом можно воспользоваться символом EOF? Обычно его определение содержится в файле . Общеупотребительным является определение

#define EOF (-1)

Это дает возможность использовать в программах выражения, подобные, например, такому

while ((ch=getchar)!= EOF)

Поэтому мы можем переписать нашу предыдущую программу, осущecтвляющyю ввод и эхо-печать символов, так:

/* ввод-вывод4 */

#include < stdio.h>

main

{

int ch;

while ((ch = getchar)! = EOF)

putchar (ch);

}

Отметим следующие моменты:

1. Нам не нужно самим определять признак EOF, поскольку заботу об этом берет на себя файл stdio.h.

2. Мы можем не интересоваться фактическим значением символа EOF, поскольку директива #define, имеющаяся в файле stdio.h, позволяет нам использовать его символическое представление.

3. Мы изменили тип переменной ch с char на int. Мы поступили так потому, что значениями переменных типа char являются целые числа без знака в диапазоне от 0 до 255, a признак EOF может иметь числовое значение – 1. Эта величина недопустима для переменной типа char, но вполне подходит для переменной типа int. К счастью, функция getchar фактически возвращает значение типа int, поэтому она в состоянии прочесть символ EOF.

4. Переменная ch целого типа никак не может повлиять на работу функции putchar. Она просто выводит на печать символьный эквивалент значения аргумента.

5. При работе с данной программой, когда символы вводятся с клавиатуры, необходимо уметь вводить признак EOF. He думайте, что вы можете просто указать буквы E-О-F или число – 1. (Число – 1 служит эквивалентом кода ASCII данного символа, а не самим этим символом. Вместо этого вам необходимо узнать, какое представление используется в вашей системе. В большинстве реализаций операционной системы UNIX, например, ввод знака [CTRL/d] (нажать на клавишу [d], держа нажатой клавишу [CTRL]) интерпретируется как признак EOF. Во многих микрокомпьютерах для той же цели используется знак [CTRL/z].

Поделиться с друзьями: