главнаяЛекция |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Лекция №4Тема:
Функции библиотеки по категориям
|
Функция
|
Использование
|
memcopy |
Копирует
символы из одного буфера в
другой до тех пор, пока не будет скопирован заданный символ или ранее указанное количество символов. |
memchr | Возвращает указатель на
первое появление в буфере заданного символа внутри специфицированного числа символов. |
memcmp |
Сравнивает
указанное количество
символов в двух буферах. |
memicmp | Сравнивает указанное количество символов из двух буферов вне зависимости от верхнего/нижнего регистра. |
memcpy | Копирует указанное количество символов из одного буфера в другой. |
memset | Использует данный символ
для заполнения указанного количества байтов в буфере. |
movedata | Копирует указанное количество символов из одного буфера в другой, даже если буферы расположены в разных сегментах. |
Процедуры манипуляции с буферами полезны при работе с об-
ластями памяти и осуществляют пересылки данных по принципу "сим-
вол-символ". Буфера являются массивами символов (байтов). Однако
в отличие от строк, они обычно не завершаются нулевым символом
'\0'. Поэтому процедуры манипуляции с буферами всегда используют
длину или счетчик в качестве аргумента. Объявления процедур мани-
пуляции с буферами содержатся в include-файлах
<memory.h> и
<string.h>.
Классификация и преобразование символов
Функция
|
Использование
|
isalnum
|
Проверяет
данные на алфавитно-
цифровые символы. |
isalfa
|
Проверяет
данные на буквенные символы.
|
isascii
|
Проверяет
данные на символы ASCII.
|
iscntrl
|
Проверяет
данные на управляющие
символы. |
isdigit
|
Проверяет
данные на десятичные цифры.
|
isgraph
|
Проверяет
данные на печатаемые
символы, за исключением символа пробела. |
islower
|
Проверяет
строчные буквы.
|
isprint
|
Проверяет
печатаемые символы.
|
ispunct
|
Проверяет
знаки пунктуации.
|
isspace
|
Проверяет
пробельные символы.
|
isupper
|
Проверяет
прописные буквы.
|
isxdigit
|
Проверяет
шестнадцатиричные цифры.
|
toascii
|
Преобразует
символы в ASCII.
|
tolower
|
Проверяет
и преобразует буквы в
строчные, если они были прописными (из верхнего регистра в нижний). |
toupper
|
Проверяет
и преобразует буквы в
прописные, если они были строчными (из нижнего регистра в верхний). |
_tolower
|
Преобразует
символы в коды нижнего
регистра (безусловное преобразование) |
_toupper
|
Преобразует
символы в коды верхнего
регистра (безусловное преобразование) |
Процедуры классификации и
преобразования символов позво-
ляют проверять отдельные символы различными способами и делать
преобразования символов из верхнего регистра в нижний и наоборот.
Процедуры классификации и преобразования символов идентифицируют
символ, находя соответствующий ему код в таблице классификации
кодов. Рекомендуется использование этих процедур для классифика-
ции символов вместо написания тестовых проверок типа:
if ((c>=0) !! (c<=0x7f))
Процедуры tolower и toupper реализованы в виде функций
и
макро, остальные процедуры этой категории реализуются только как
макро. Все макро определены в include-файле <ctype.h>. Он
должен
быть подключен иначе макро не будут определены.
Макро tolower и toupper вычисляют свои аргументы дважды,
что может привести к побочным эффектам, а , следовательно, к по-
лучению некорректных результатов. Поэтому полезно использовать
версии функций этих процедур.
Макро-версии tolower и toupper используются по умолчанию,
когда подключен <ctype.h>. Для использования вместо них версий
функций нужно записать препроцессорную директиву #undef для
tolower и toupper после директивы #include для <ctype.h>,
но пе-
ред тем, как эти процедуры будут вызваны. В результате этих дейс-
твий их макроопределения будут заменены и случаи обращения к
tolower и toupper будут трактоваться как вызов соответствующих
функций.
Если в программах используются версии функций tolower и
toupper, а другие макро для проверок символов в программах не ис-
пользуются, можно просто не подключать файл <ctype.h>. В
этом
случае макроопределения для tolower и toupper не будут действи-
тельны, так как будут использованы версии их функций.
Подключение include-файла <stdlib.h>, в котором содержат-
ся объявления функций tolower и toupper, вместо файла <ctype.h>
позволяет избежать конфликта с макроопределениями. Если нужно ис-
пользовать tolower и toupper в качестве функций и подключить
объ-
явления из <stdlib.h>, нужно выполнить следующие действия:
ФУНКЦИЯ
|
ИСПОЛЬЗОВАНИЕ
|
atof
|
Преобразовывает
строку во float.
|
atoi
|
Преобразовывает
строку в int.
|
atol
|
Преобразовывает
строку в long.
|
ecvt
|
Преобразовывает
double в строку.
|
fcvt
|
Преобразовывает
double в строку.
|
gcvt
|
Преобразовывает
double в строку.
|
itoa
|
Преобразовывает
int в строку.
|
ltoa
|
Преобразовывает
long в строку.
|
strtod
|
Преобразовывает
строку в double.
|
strtol
|
Преобразовывает
строку в long
десятичное целое, которое равно числу со специальным основанием. |
ultoa
|
Преобразовывает
unsigned long в
строку. |
Процедуры преобразования данных
преобразуют числа в сим-
вольные строки, соответствующие кодам ASCII, и наоборот. Эти про-
цедуры реализуются как функции и все их объявления
содержатся в
include-файле <stdlib.h>. Функция atof, которая преобразует
стро-
ки в данные с плавающей точкой, определена также в <math.h>.
ФУНКЦИЯ
|
ИСПОЛЬЗОВАНИЕ
|
chdir
|
Изменяет текущее рабочее
оглавление |
getcwd
|
Получает текущее рабочее
оглавление |
mkdir
|
Создает новое оглавление |
rmdir
|
Удаляет оглавление |
Процедуры управления директориями позволяют осуществить
доступ, модификацию , и получать информацию о структуре оглавле-
ния непосредственно из программы. Можно получить текущее рабочее
оглавление, изменить оглавление, дополнить или удалить его.
Процедуры управления оглавлениями являются функциями и
объявляются в include-файле <direct.h>.
ФУНКЦИЯ
|
ИСПОЛЬЗОВАНИЕ
|
access
|
Проверяет
разрешенный доступ к файлу
|
chmod
|
Изменяет
разрешенный доступ к файлу
|
chsize
|
Изменяет
размер файла
|
filelength
|
Контролирует
длину файла
|
fstat
|
Получает
информацию о состоянии
текущего handle-ра файла |
isatty
|
Проверяет
тип устройства
|
locking
|
Защищиет
области файла от
несанкционированного доступа. |
mktemp
|
Создает
уникальное имя файла
|
remove
|
Удаляет
файл
|
rename
|
Переименовывает
файл
|
setmode
|
Устанавливает
режим обработки файла
|
stat
|
Получает
по имени файла информацию о
статусе файла |
umask
|
Устанавливает
маску доступа по
умолчанию |
unlink
|
Удаляет
файл
|
Процедуры управления файлами
работают с файлом, на кото-
рый указывает path-имя или текущий handle-р. Они модифицируют
или
предоставляют информацию об указанном файле. Все эти процедуры,
кроме fstat и stat, объявляются в include-файле <io.h>.
Объявле-
ния функций fstat и stat содержатся в <sys\stat.h>.
Объявления
функций remove и rename есть также и в <stdio.h>.
Процедуры access, chmod, remove, rename, stat, unlink
оперируют с файлами, для которых указано path-имя или имя файла.
Процедуры chsize, filelength, isatty, locking, sermode, fstat ра-
ботают с файлами, определенными по handle-ру.
Функции процедур mktemp, umask несколько отличаются от
перечисленных ранее процедур. Процедура mktemp создает уникальное
имя файла. Программы могут использовать mktemp для создания уни-
кальных имен файлов, которые не будут совпадать с именами уже
существующих файлов. Процедура umask устанавливает маску дос-
тупа по умолчанию для некоторых новых файлов, созданных в прог-
рамме. Маска может подавить способы доступа, заданные при вызовах
open или creat для нового файла.
Ввод и вывод
Процедуры ввода/вывода стандартной библиотеки Си позволя-
ют читать и записывать данные из/в файлов и устройств. В языке Си
предопределенных структур файлов нет, все данные обрабатываются
как последовательность байтов.
Доступны три типа функций ввода/вывода:
1) потоковый ввод/вывод;
2) низкоуровневый ввод/вывод;
3) консольный ввод/вывод и ввод/вывод портов.
Функции потока обрабатывают данные файла или элементарную
группу данных как поток индивидуальных символов. Выбирая среди
множества функций потока требуемую, можно обрабатывать данные
различных форматов и размеров от отдельных символов до больших
структур данных. Когда файл открыт для ввода/вывода при использо-
вании функций потока, он соединяется со структурой типа FILE, в
которой содержится базовая информация о файле. Если поток откры-
вается, то возвращается указатель на структуру
типа FILE. Этот
указатель (также называемый указателем на поток просто поток) ис-
пользуется в подпоследовательности операций, относящихся к файлу.
Функции потока обеспечивают буферизованный, форматирова-
ный и неформатированный ввод/вывод.
Когда поток буферизован, то данные, считываемые или запи-
сываемые в поток, собираются в промежуточной памяти, называемой
буфером. При записи, когда буфер полон либо закрывается поток
или программа заканчивается нормально, содержимое буфера записы-
вается в соответствующее окончательное место.
При чтении блок данных размещается
во входном буфере и данные считываются из буфера. Если входной поток пуст
- следующий блок данных переносится
в буфер. Буферизация обеспечивает более эффективный ввод/вывод,
поскольку система может передавать большие блоки данных в отдель-
ных операциях ввода/вывода, что быстрее, чем преобразования каж-
дый раз на операциях ввода/вывода, когда объекты данных читаются
или записываются в поток. Однако, при аварийном окончании прог-
раммы выходной буфер может не обновиться и в результате данные
будут потеряны.
Процедуры консольного ввода/вывода и ввода/вывода портов
рассматриваются как расширение процедур потока. Они позволяют
считывать и записывать на терминал (консоль) или вводить/выводить
в порты (например, порт печати). Процедуры ввода/вывода порта
позволяют считывать и записывать данные в байты. Процедуры вво-
да/вывода на консоль имеют некоторые дополнительные опции. Напри-
мер, нужно выявить символ, введенный с консоли. Можно отображать
введенные символы посредством эхо-печати или же считывать символы
без нее.
"Низкоуровневые" процедуры ввода/вывода не выполняют бу-
феризации и форматирования. Они рассматриваются как вызов возмож-
ностей ввода/вывода ОС. Эти процедуры предоставляют доступ к фай-
лам и периферийным устройствам на более элементарном уровне, чем
функции потока. Если файл открывается при помощи низкоуровневой
процедуры ввода, то ему соответствует handle-р. Handle-р - это
целое число, которое в последующих операциях используется для
ссылки на файл.
Процедуры потока
ПРОЦЕДУРА
|
ИСПОЛЬЗОВАНИЕ
|
clearerr
|
Очищает
индикатор ошибок потока
|
fclose
|
Закрывает
поток
|
fcloseall
|
Закрывает
все открытые потоки
|
fdopen
|
Открывает
поток, на который указывает
handle-р |
feof
|
Проверяет
поток на конец файла (EOF)
|
ferror
|
Проверяет
ошибки в потоке
|
fflush
|
Сбрасывает
поток
|
fgets
|
Читает
символ из потока (версия
функции) |
fgetchar
|
Читает
символ из <stdin> (версия
функции) |
fgets
|
Читает
строку из потока
|
fileno
|
Выбирает
handle-р, соответствующий
потоку |
flushall
|
Сбрасывает
все потоки
|
fopen
|
Открывает
поток
|
fprintf
|
Записывает
форматированные данные в
поток |
fputc
|
Записывает
символ в поток (версия
функции) |
fputchar
|
Записывает
символ в <stdout> (версия
функции) |
fputs
|
Записывает
строку в поток
|
fread
|
Читает
неформатированные данные из
потока |
freopen
|
Переназначает
указатель на FILE
|
fscanf
|
Читает
форматированные данные из потока
|
fseek
|
Перемещает
указатель на файл к
заданному положению |
ftell
|
Выбирает
текущую позицию указателя на
файл |
fwrite
|
Записывает
неформатированную группу
данных в поток |
getc
|
Читает
символ из потока (версия макро)
|
getchar
|
Читает
символ из потока (версия макро)
|
gets
|
Читает
символ из потока (версия макро)
|
getw
|
Читает
двоичный int из потока
|
printf
|
Читает
двоичный int из потока
|
putc
|
Записывает
символ в поток (версия
макро) |
putchar
|
Записывает
символ в <stdout> (версия
макро) |
puts
|
Записывает
строку в поток
|
putw
|
Записывает
двоичный int в поток
|
rewind
|
Перемещает
указатель на файл к началу
потока |
rmtmp
|
Уничтожает
временный файл, созданный
посредством функции tmpfile |
scanf
|
Читает
форматированные данные из
<stdin> |
setbuf
|
Управляет
буферизацией потока
|
setvbuf
|
Управляет
буферизацией потока и
размером буфера |
sprintf
|
Записывает
форматированные данные в
строку |
sscanf
|
Читает
форматированные данные из
строки |
tempnam
|
Генерирует
имя временного файла в
выбранном директории |
tmpfile
|
Создает
временный файл
|
tmpnam
|
Генерирует
имя временного файла
|
ungetc
|
Возвращает
символ в буфер
|
vfprintf
|
Записывает
форматированные данные в
поток |
vprintf
|
Записывает
форматированные данные в
<stdout> |
vsprintf
|
Записывает
форматированные данные в
строку |
Для использования в программах функций потока нужно
подключать в программы include-файл <stdio.h>.
В этом фай-
ле определены константы, типы и структуры, которые исполь-
зуются в функциях потока, а также содержатся объявления
функций и определения макро для процедур потока.
Некоторые
константы, определенные в этом include-файле, могут приме-
няться в программах пользователей. Манифестная константа
eof определяется как значение, возвращаемое при достижении
конца файла;null- нулевой указатель, file - структура,
содержащая информацию о поток bufsiz- константа, опре-
деляющая размер буфера в байтах.
Две функции:
printf для вывода и scanf для ввода (следующий раз-
дел) позволяют преобразовывать численные величины в символьное предс-
тавление и обратно. Они также позволяют генерировать и интерпретиро-
вать форматные строки. Мы уже всюду в предыдущих главах неформально
использовали функцию printf; здесь приводится более полное и точное
описание. Функция
преобразует, определяет формат и печатает свои аргументы в стандарт-
ный вывод под управлением строки control. Управляющая строка содержит
два типа объектов: обычные символы, которые просто копируются в вы-
ходной поток, и спецификации преобразований, каждая из которых вызы-
вает преобразование и печать очередного аргумента printf.
Каждая спецификация преобразования начинается с символа % и за-
канчивается символом преобразования. Между % и символом преобразова-
ния могут находиться:
- Знак минус, который указывает о выравнивании преобразованного
аргумента по левому краю его поля.
-Строка
цифр, задающая минимальную ширину поля. Преобразо-
ванное число будет напечатано в поле по крайней мере этой
ширины, а если необходимо, то и в более широком. Если пре-
образованный аргумент имеет меньше символов, чем указанная
ширина поля, то он будет дополнен слева (или справа, если
было указано выравнивание по левому краю)заполняющими сим-
волами до этой ширины. Заполняющим символом обычно являет-
ся пробел, а если ширина поля указывается с лидирующим ну-
лем, то этим символом будет нуль (лидирующий нуль в данном
случае не означает восьмеричной ширины поля).
- Точка, которая отделяет ширину поля от следующей строки
цифр.
- Строка цифр (точность), которая указывает максимальное
число символов строки, которые должны быть напечатаны, или
число печатаемых справа от десятичной точки цифр для пере-
менных типа float double.
- Модификатор длины L, который указывает, что соответствую-
щий элемент данных имеет тип long, а не int.
Ниже приводятся символы преобразования и их смысл:
D - аргумент преобразуется к десятичному виду.
O - Аргумент преобразуется в беззнаковую восьмеричную форму
(без лидирующего нуля).
X - Аргумент преобразуется в беззнаковую шестнадцатеричную
форму (без лидирующих 0X).
U - Аргумент преобразуется в беззнаковую десятичную форму.
C - Аргумент рассматривается как отдельный символ.
S - Аргумент является строкой: символы строки печатаются до
тех пор, пока не будет достигнут нулевой символ или не бу-
дет напечатано количество символов, указанное в специфика-
ции точности.
E - Аргумент, рассматриваемый как переменная типа float или,double
преобразуется в десятичную форму в виде
[-]M.NNNNNNE[+-]XX, где длина строки из N определяется
указанной точностью. Точность по умолчанию равна 6.
F - Аргумент, рассматриваемый как переменная типа float или
double, преобразуется в десятичную форму в виде
[-]MMM.NNNNN, где длина строки из N определяется указанной
точностью. Точность по умолчанию равна 6. отметим, что эта
точность не определяет количество печатаемых в формате F
значащих цифр.
G - Используется или формат %E или %F, какой короче; незна-
чащие нули не печатаются.
Если идущий за % символ не является символом преобразования,
то печатается сам этот символ; следовательно,символ % можно
напечатать, указав %%.
Большинство из форматных преобразований очевидно и было
проиллюстрировано в предыдущих главах. Единственным исключе-
нием является то, как точность взаимодействует со строками.
Следующая таблица демонстрирует влияние задания различных
спецификаций на печать "HELLO, WORLD" (12 символов). Мы по-
местили двоеточия вокруг каждого поля для того, чтобы вы
могли видеть его протяженность.
Предостережение: printf использует свой первый аргумент
для определения числа последующих аргументов и их типов. Ес-
ли количество аргументов окажется недостаточным или они бу-
дут иметь несоответственные типы, то возникнет путаница и вы
получите бессмысленные результаты.
ФУНКЦИЯ scanf
Осуществляющая ввод функция scanf является аналогом printf
и поз-
воляет проводить в обратном направлении многие из тех же самых преоб-
разований. Функция
scanf(CONTROL, ARG1, ARG2, ...)
читает символы из стандартного ввода, интерпретирует их в соответс-
твии с форматом, указанном в аргументе control, и помещает результаты
в остальные аргументы. Управляющий аргумент описывается ниже; другие
аргументы, каждый из которых должен быть указателем,
определяют, куда
следует поместить соответствующим образом преобразованный ввод.
Управляющая строка обычно содержит спецификации преобразования,
которые используются для непосредственной интерпретации входных пос-
ледовательностей.
Управляющая строка может содержать:
- пробелы,
табуляции или символы новой строки ("символы пус-
тых промежутков"), которые игнорируются.
- обычные символы (не %), которые предполагаются совпадающи-
ми со следующими отличными от символов пустых промежутков
символами входного потока.
- спецификации преобразования, состоящие из символа %, нео-
бязательного символа подавления присваивания *, необяза-
тельного числа, задающего максимальную ширину поля и сим-
вола преобразования.
Спецификация преобразования управляет преобразованием следующего
поля ввода. нормально результат помещается в переменную, которая ука-
зывается соответствующим аргументом. Если, однако , с помощью символа
* указано подавление присваивания, то это поле ввода просто пропуска-
ется и никакого присваивания не производится. Поле ввода определяется
как строка символов, которые отличны от символов простых промежутков;
оно продолжается либо до следующего символа пустого промежутка, либо
пока не будет исчерпана ширина поля, если она указана. Отсюда следу-
ет, что при поиске нужного ей ввода, функция scanf будет пересекать
границы строк, поскольку символ новой строки входит в число пустых
промежутков.
Символ преобразования определяет интерпретацию поля ввода; сог-
ласно требованиям основанной на вызове по значению семантики языка
"си" соответствующий аргумент должен быть указателем.
Допускаются следующие символы преобразования:
D - на вводе ожидается десятичное целое; соответствующий
аргумент должен быть указателем на целое.
O - На вводе ожидается восьмеричное целое (с лидирующим ну-
лем или без него); соответствующий аргумент должен быть
указателем на целое.
X - На вводе ожидается шестнадцатеричное целое (с лидирующи-
ми 0X или без них); соответствующий аргумент должен быть
указателем на целое.
H - На вводе ожидается целое типа short; соответсвующий
ар-
гумент должен быть указателем на целое типа short.
C - Ожидается отдельный символ; соответствующий аргумент
должен быть указателем на символы; следующий вводимый
символ помещается в указанное место. Обычный пропуск сим-
волов пустых промежутков в этом случае подавляется; для
чтения следующего символа, который не является символом
пустого промежутка, пользуйтесь спецификацией преобразо-
вания %1S.
S - Ожидается символьная строка; соответствующий аргумент
должен быть указателем символов, который указывает на
массив символов, который достаточно велик для принятия
строки и добавляемого в конце символа \0.
F - Ожидается число с плавающей точкой; соответствующий ар-
гумент должен быть указателем на переменную типа float.
Е - символ преобразования E является синонимом для F. Формат
ввода переменной типа float включает необязательный знак,
строку цифр, возможно содержащую десятичную точку и нео-
бязательное поле экспоненты, состоящее из буквы E, за ко-
торой следует целое, возможно имеющее знак.
Перед символами преобразования
D, O и X может стоять L, которая
означает , что в списке аргументов должен находиться указатель на пе-
ременную типа long, а не типа int. Аналогично, буква L может
стоять
перед символами преобразования E или F, говоря о том, что в списке
аргументов должен находиться указатель на переменную типа double,
а
не типа float.
Например, обращение
со строкой на вводе
25 54.32E-1 THOMPSON
приводит к присваиванию I значения 25,X - значения 5.432 и NAME -
строки "THOMPSON", надлежащим образом законченной символом \0.
эти
три поля ввода можно разделить столькими пробелами, табуляциями и
символами новых строк, сколько вы пожелаете. Обращение
с вводом
56789 0123 45A72
присвоит I значение 56, X - 789.0, пропустит 0123 и поместит в NAME
строку "45". при следующем обращении к любой процедуре ввода
рассмот-
рение начнется с буквы A. В этих двух примерах NAME является указате-
лем и, следовательно, перед ним не нужно помещать знак &.
Заключительное предостережение: аргументы функции SCANF должны
быть указателями. Несомненно наиболее распространенная ошибка состоит
в написании
snanf("%D", N);
вместо
scanf("%D", &N);
Поток должен быть открыт посредством
функций fdopen,
fopen, freopen перед вводом или выводом, выполняемым в данном по-
токе. Поток может быть открыт либо только для чтения, либо только
для записи, либо одновременно для того и другого и либо в текс-
товом, либо в двоичном режиме.
Вышеперечисленные функции возвращают указатель
на пере-
менную типа FILE и используют этот указатель для ссылки на поток.
При вызове любой из данных функций нужно возвращаемое значение
направить в переменную типа указателя на FILE и использовать эту
переменную как ссылку на открытый поток. Например, если в прог-
рамме содержится строка:
infile = fopen("test.dat", "r"); ,
тогда нужно использовать переменную infile-типа указателя на
FILE, как ссылку на поток.
Предопределенные указатели
потока: stdin,
stdout, stderr, stdaux, stdprn.
В самом начале выполнения
программы автоматически откры-
ваются 5 потоков. Эти потоки являются потоками стандартного вво-
да, стандартного вывода, стандартных ошибок, стандартного допол-
нительного и стандартной печати. По умолчанию потоки стандартного
ввода, вывода и ошибок направлены на консоли пользователей. Это
обозначает, что всякий раз, когда программа предполагает ввод из
"стандартного ввода", она воспринимает его с консоли. Аналогично
программа, предполагающая вывод в "стандартный вывод", распечаты-
вает свои данные на консоль. Сообщения об ошибках, сформированные
посредством библиотечных процедур, пересылаются к "стандартным
ошибкам". Это означает, что на консоли пользователя появляются
сообщения об ошибках.
Назначение двух оставшихся потоков - "стандартного допол-
нительного" и "стандартной печати" - зависит от конфигурации
компьютера. Эти потоки обычно направлены соответственно на допол-
нительный порт и печать, но в некоторых системах они могут быть
не установлены. Перед использованием этих потоков необходимо про-
верить конфигурацию компьютера.При использовании функций потока
ссылки на стандартные потоки осуществляются при помощи следующих
предопределенных указателей на тип FILE.
ПОТОК
|
УСТРОЙСТВО
|
stdin
|
стандартный
ввод
|
stdout
|
стандартный
вывод
|
stderr
|
стандартные
ошибки
|
stdaux
|
стандартный
дополнительный
|
stdprn
|
стандартная
печать
|
Эти указатели могут быть применены в любой функции, тре-
бующей указатель на поток как аргумент. В некоторых функциях, та-
ких как getchar и putchar, разрешается автоматическое использова-
ние <stdin> и <stdout>. Указателями на stdin,
stdout, stderr яв-
ляются константы, а не переменные; нельзя назначать им значения
указателей на новые потоки.
Управление буферизацией потока
Файлы, открытые
при помощи функций потока, буферизуются
по умолчанию, кроме предварительно открытых потоков stdin,
stdout, stderr, stdaux, stdprn. Потоки stderr и stdaux не
являют-
ся буферизованными до тех пор, пока они не будут использованы в
одном из семейств функций printf и scanf, в каждом из которых
назначается временный буфер для этих потоков. Эти два потока мож-
но сделать буферизованными, используя функции setbuf и setvbuf.
Потоки stdin, stdout и stdprn являются буферизованными.
Буфер,
созданный этими потоками, сбрасывается, если он полон, или, если
завершается функция, вызвавшая ввод/вывод. Применяя функции
setbuf и setvbuf, поток можно сделать не буферизованным
или сог-
ласовать буфер с небуферизованным потоком. Буферы, размещаемые
системой, не доступны для пользователей, а буферы, размещаемые
посредством данных функций, именуются пользователем и используют-
ся им как обычные переменные. Буферы могут быть любых размеров:
если использовалась функция setbuf - размер буфера устанавливает-
ся константой BUFSIZ, определенной в <stdio.h>, если
использова-
лась функция setvbuf - размер буфера устанавливается самостоя-
тельно. Буферы автоматически сбрасываются, если они полны, если
соответствующий, связанный с ним файл закрывается, или когда
программа нормально завершается. Буферы можно сбросить в любое
время, использовав для этого процедуры fflush и flushall.
Проце-
дура fflush сбрасывает отдельный определенный поток, а flushall
-
все открытые и буферизованные потоки.
Функции fclose
и fcloseall закрывают соответственно поток
и потоки. Функция fclose закрывает отдельный определенный поток,
fcloseall - закрывает все открытые потоки, за исключением stdin,
stdout, stderr, stdaux, stdprn. Если в программе поток не закры-
вается, то он автоматически закроется по окончании работы прог-
раммы.
Однако, существует очень хороший практический совет: зак-
рывать поток по окончании работы с ним, так как число потоков,
которые могут быть открыты одновременно, ограничено.
Чтение
и запись данных
Операции чтения и записи потока всегда начинаются с теку-
щей позиции потока, известной как "указатель на файл" для потока.
После использования операций чтения/записи этот указатель изменя-
ется и соответствует новой позиции в файле. Например, при считы-
вании отдельного символа из потока, указатель увеличивается
(сдвигается) на один байт, поэтому следующая операция начинается
с первого несчитанного символа. Если поток открыт для дополнения,
то перед операцией записи указатель автоматически смещается к
концу файла.
Макро feof определяет состояние конца файла
в потоке. Ин-
дикатор конца файла устанавливается один раз. Он остается уста-
новленным до закрытия файла или до вызова функций clearerr или
rewind. Указатель на файл можно позиционировать в любом месте
файла, используя для этого функцию fseek. Следующая операция про-
изводится на специфицированной позиции. Функция rewind перемещает
указатель к началу файла. Для определения текущей позиции указа-
теля на файл применяется функция ftell.
Потоки, связанные с устройством, например с консолью, не
имеют указателя на файл. Данные, вводимые с консоли и выводимые
на консоль, не могут быть случайно доступными. В процедурах, ус-
танавливающих или изменяющих позицию указателя (таких как fseek,
ftell, rewind), может получиться неопределенный результат, если
используемый поток связан с потоком.
Когда в потоковых операциях возникают ошибки, то для по-
тока устанавливается индикатор ошибки. Для проверки индикатора
ошибки и места ее возникновения используется макро
ferror. Если
ошибка возникла, то индикатор ошибки остается установленным до
тех пор, пока файл не закроется, или пока индикатор не будет очи-
щен посредством вызова процедур clearerr и rewind.
ПРОЦЕДУРА
|
ИСПОЛЬЗОВАНИЕ
|
close
|
Закрывает
файл
|
creat
|
Создает
файл
|
dup
|
Создает
копию handle-ра файла
|
dup2
|
Переназначает
копию handle-ра файла
|
eof
|
Проверяет
на конец файла
|
lseek
|
Перемещает
указатель на файл к
выбранному месту |
open
|
Открывает
файл
|
read
|
Читает
данные из файла
|
sopen
|
Открывает
файл для разделенного
использования |
tell
|
Берет
текущую позицию указателя на
файл |
write
|
Записывает
данные в файл
|
Низкоуровневый
ввод/вывод вызывается для того, чтобы бу-
феризовать и не форматировать данные. Файлы, открытые при помощи
низкоуровневых вызовов, определяются файловыми handle-рами. ОС
использует эти целые значения для ссылки на файл. Для открытия
файлов используется функция open. В отличие от потоковых функций,
для функций низкого уровня не требуется include-файл <stdio.h>.
Однако, в этом файле определены некоторые общие константы, напри-
мер, индикатор конца файла eof. Если эти константы используются
в
программах, то в эти программы необходимо включение данного inc-
lude-файла. В include-файле <io.h>
заданы объявления функций низ-
кого уровня.
Открытие
файла
Перед выполнением низкоуровневых функций ввода/вывода файл
должен быть открыт посредством использования функций open, sopen
или creat. Файл также может быть открыт для чтения, записи, или
чтения и записи одновременно, и либо в текстовом, либо в двоичном
режиме. Когда файл открывается, то должен быть подключен
include-файл <fcntl.h>, так как в нем описываются флаги,
применя-
емые в функции open. В некоторых случаях также должны быть подк-
лючены файлы <sys\types.h> и <sys\stat.h>.
При выполнении
программы всегда определены 5 handle-ров,
соответствующие стандартному вводу, стандартному выводу, стандар-
тным ошибкам, стандартному дополнительному потоку и стандартной
печати. Для доступа к этим 5 стандартным потокам в программе мо-
гут быть вызваны низкоуровневые функции при помощи предопределен-
ных handle-ров.
Поток
|
Handle-р
|
stdin |
0
|
stdout |
1
|
stderr |
2
|
stdaux |
3
|
stdprn |
4
|
Эти файлы можно использовать в программах без предваритель-
ного открытия соответствующих файлов. Они автоматически открыва-
ются в начале работы программы, как показано в фрагменте малень-
кой программы, использующей функцию fileno для печати значений
файловых handle-ров, определенных потоками стандартного ввода,
вывода, ошибок, дополнительного, печати.
Тогда на выходе будет следующая информация:
Две базовые функции
- read и write - выполняют ввод-чтение
и вывод-запись. Аналогично потоковым функциям, операции ввода/вы-
вода начинаются с текущей позиции в файле. При выполнении опера-
ций ввода/вывода текущая позиция каждый раз корректируется (об-
новляется). Для проверки конца файла может быть использована про-
цедура eof. В случае возникновения ошибки низкоуровневыми проце-
дурами ввода/ вывода устанавливается переменная errno. Поэтому
чтобы распечатать информацию об ошибках ввода/вывода, нужно ис-
пользовать функцию perror, а для размещения данной информации в
строку - функцию strerror. Использованием функции lseek
можно пе-
ремещать указатель на файл в любое место файла; следующая опера-
ция будет выполняться с установленной ранее позиции. Для опреде-
ления текущей позиции указателя на файл используется функция
tell.
Устройства (такие как консоль) не имеют указателей на файл.
Процедуры lseek и tell вырабатавают неопределенный результат,
ес-
ли они используются для подобных устройств.
Функция close закрывает открытый файл. Если программа за-
канчивает выполнение, все открытые файлы автоматически закрывают-
ся. Однако на практике рекомендуется закрывать все открытые файлы
по окончании работы с ними, так как количество одновременно отк-
рытых файлов ограничено.