Шрифт:
РИС. 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].
Приведем результат работы программы ввод-вывод4 в системе, обладающей буферизованным вводом:
0на идет во всей красе -
Она идет во всей красе -
Светла, как ночь ее страны.Светла, как ночь ее страны.
Лорд Байрон
Лорд Байрон
[CTRL/z]
Каждый раз при нажатии клавиши [ввод] производится обработка символов, попавших в буфер, и копия строки выводится на печать. Это продолжается до тех пор, пока мы не введем признак EOF.
Давайте остановимся и подумаем о возможностях программы ввод-вывод4. Она осуществляет вывод на экран символов независимо от того, откуда они поступают. Предположим, мы сумели сделать так, что программа вводит символы из некоторого файла. В этом случае она будет осуществлять вывод содержимого файла на экран и остановится только тогда, когда достигнет конца файла, поскольку обнаружит признак EOF. Или предположим, что у нас есть способ организовать вывод результатов работы программы в некоторый файл. Тогда можно набрать какой-нибудь текст на клавиатуре и при помощи программы ввод-вывод4 поместить его во внешнюю память. Или мы могли бы выполнить оба действия одновременно: например, осуществить ввод данных из одного файла и переслать их в другой. В этом случае программа ввод-вывод4 использовалась бы для копирования файлов. Следовательно, наша маленькая программа могла бы просматривать содержимое файлов, создавать новые файлы и получать копии файлов. Неплохо для такой короткой программы! Ключ к решению этих проблем - в управлении вводом и выводом. Это послужит темой представленного ниже обсуждения.
ПЕРЕКЛЮЧЕНИЕ И РАБОТА С ФАЙЛАМИ
Понятие ввода-вывода включает в себя функции, данные и устройства. Рассмотрим, например, нашу программу ввод-вывод4. В ней используется функция getchar, осуществляющая ввод, причем устройство ввода - клавиатура (в соответствии с нашим предположением), а входные данные - отдельные символы. Нам бы хотелось сохранить функции ввода и тип данных, но изменить источник их поступления в программу. Зададимся вопросом: откуда программа узнает, где искать входные данные?
По умолчанию Си-программа рассматривает "стандартный ввод" как источник поступления данных. "Стандартным вводом называется устройство, принятое в качестве обычного средства ввода данных в машину. Это может быть устройство чтения данных с магнитной ленты или перфокарт, телетайп или (как мы продолжаем считать) терминал. Современная машина - это послушный инструмент, и мы можем воздействовать на нее так, чтобы она вводила данные из любого источника. В частности, мы можем сообщить программе, что источник входных данных - файл, а не клавиатура.