Стивен Прата - Язык программирования C. Лекции и упражнения (6-е изд.) 2015
- Название:Язык программирования C. Лекции и упражнения (6-е изд.) 2015
- Автор:
- Жанр:
- Издательство:Вильямс
- Год:0101
- ISBN:нет данных
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Стивен Прата - Язык программирования C. Лекции и упражнения (6-е изд.) 2015 краткое содержание
Язык программирования C. Лекции и упражнения (6-е изд.) 2015 - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
298 глава 8
Когда вы применяете стандартный пакет ввода-вывода, вы защищены от воздействия таких отличий. Следовательно, для проверки на предмет символа новой строки можно использовать конструкцию if (ch == ‘\n'). Если система применяется комбинация символов возврата каретки и перевода строки, то функции ввода-вывода выполняют автоматическую трансляцию между двумя этими представлениями в обоих направлениях.
Концептуально программа на С имеет дело с потоком, а не напрямую с файлом. Поток — это идеализированное течение данных, на которое отображается действительный ввод или вывод. Это означает, что разнообразные виды ввода с отличающимися свойствами представлены с помощью потоков, имеющих более унифицированные свойства. Тогда процесс открытия файла становится процессом ассоциирования потока с файлом, а чтение и запись осуществляются через поток.
Файлы подробно обсуждаются в главе 13. Для целей настоящей главы просто запомните, что в языке С устройства ввода и вывода трактуются таким же образом, как обычные файлы на устройствах хранения. В частности, клавиатура и устройство отображения считаются файлами, автоматически открываемыми каждой программой на С. Клавиатурный ввод представлен потоком по имени stdin, а вывод на экран (или на телетайп либо другое устройство вывода) представлен потоком по имени stdout. Функции getchar(), putchar(), printf() и scanf() являются членами стандартного пакета ввода-вывода, и все они имеют дело с двумя упомянутыми потоками.
Одно из следствий всего этого заключается в том, что при работе с клавиатурным вводом можно использовать те же самые приемы, как и при работе с файлами. Например, программе, читающей файл, необходим способ обнаружения конца файла, чтобы знать, где останавливать чтение. Поэтому функции для ввода в С оснащены встроенным средством обнаружения конца файла. Поскольку клавиатурный ввод трактуется подобно файлу, вы должны иметь возможность применять это средство обнаружения конца файла также и в данном случае. Давайте посмотрим, как это делается, начав с файлов.
Конец файла
Операционная система нуждается в каком-то способе для выяснения, где начинается и где заканчивается каждый файл. Один из методов обнаружения конца файла предусматривает помещение в файл специального символа, помечающего его конец. В свое время такой метод использовался, к примеру, в текстовых файлах в средах one рационных систем СР/М, IBM-DOS и MS-DOS. Теперь эти операционные системы для пометки конца файла могли бы применять встроенный символ . Когда- то это было единственным средством, которое использовали операционные системы, но сейчас доступны другие варианты наподобие отслеживания размера файла. Таким образом, современный текстовый файл может содержать, а может и не содержать встроенный символ , однако если он присутствует, операционная система будет трактовать его как маркер конца файла. Этот подход иллюстрируется на рис. 8.2.
Фраза:
Робот Бишоп плавно открыл люк и ответил на свой вызов.
Фраза в файле:
Рис. 8.2. Файл с маркером конца файла
Символьный ввод-вывод и проверка достоверности ввода 299
Второй подход заключается в том, что операционная система хранит информацию о размере файла. Если файл содержит 3000 байтов, а программа прочитала 3000 байтов, значит, она достигла конца файла. Операционная система MS-DOS и ей подобные применяют этот подход для двоичных файлов, т.к. данный метод позволяет хранить в файлах все символы, в том числе . Более новые версии DOS также используют этот подход для текстовых файлов. В Unix он применяется ко всем файлам.
Такое многообразие методов поддерживается в С за счет того, что функция getchar() возвращает специальное значение при достижении конца файла независимо от того, как в действительности конец файла обнаруживается операционной системой. Этому специальному значению было назначено имя EOF (“end of file” — “конец файла”). Следовательно, возвращаемым значением функции getchar() в случае обнаружения конца файла является EOF. Функция scanf() при обнаружении конца файла также возвращает EOF. Обычно EOF определяется в файле stdio.h следующим образом:
#define EOF (-1)
Почему было выбрано значение -1? Обычно функция getchar() возвращает значение в диапазоне от 0 до 127, поскольку они соответствуют стандартному набору символов, но она может возвращать значения от 0 до 2 55, если система распознает расширенный набор символов. В любом случае значение -1 не относится ни к одному из символов, так что оно может использоваться для сообщения о конце файла.
В некоторых системах EOF может быть определено как значение, не равное -1, но это определение всегда отличается от возвращаемого значения, генерируемого допустимым входным символом. Если вы включили файл stdio.h и применяете символическую константу EOF, то не обязаны беспокоиться о ее числовом определении. Важно понимать, что EOF представляет значение, сигнализирующее об обнаружении конца файла, а не значение, действительно находящееся файле.
А как использовать EOF в программе? Нужно сравнить возвращаемое значение getchar() с EOF. Если они отличаются, конец файла пока еще не достигнут. Другими словами, можно указывать выражение, подобное следующему:
while ((ch = getchar()) != EOF) !
Что, если производится чтение клавиатурного ввода, а не файла? Большинство систем (но не все) поддерживают какой-то способ эмулировать условие конца файла с помощью клавиатуры. С учетом этого базовую программу чтения и эхо-вывода можно переписать, как показано в листинге 8.2.
Листинг 8.2. Программа echo eof .с
Обратите внимание на перечисленные ниже аспекты.
Глава 8
• Вам не придется определять EOF, т.к. об этом уже позаботился заголовочный файл stdio.h.
• Вам не нужно беспокоиться о действительном значении EOF, поскольку оператор #define в файле stdio.h позволяет иметь дело с символическим представлением EOF. Вы не должны писать код, в котором предполагается, что EOF имеет какое-то конкретное значение.
• Тип переменной ch изменен с char на int, потому что переменные типа char могут быть представлены целочисленными значениями без знака в диапазоне от 0 до 255, но EOF может иметь числовое значение -1. Такое значение недопустимо для типа char без знака, но допустимо для типа int. К счастью, функция getchar() сама имеет тип int, поэтому она может читать символ EOF. В реализациях, поддерживающих тин char со знаком, можно обойтись объявлением переменной ch как имеющей тип char, но лучше применить более общую форму.
Читать дальшеИнтервал:
Закладка: