Лекция 1

Правила оформления программ на Си/Си++.
Операции и основные типы данных.

Лекция 2

Операторы


Лекция 3

Использование библиотечных процедур СИ

 

Лекция 10

Директивы препроцессора

Лекция 11

Видимость и время жизни переменных

Лекция 12

Дополнительные возможности Си++


Лекция 13

Объектно-ориентированное программирование
 

 

 

главная

Лекция

Лекция №4

Тема: Функции библиотеки по категориям

Содержание:

 

Манипуляции с буферами

Классификация и преобразование символов

Преобразование данных

Управление директориями

Управление файлами

Ввод и вывод

Процедуры потока


Открытие потока


Предопределенные указатели потока: stdin,
stdout, stderr, stdaux, stdprn.


Управление буферизацией потока


Закрытие потоков


Чтение и запись данных


Обнаружение ошибок


Процедуры "низкого уровня"

Открытие файла


Предопределенные handle-ры


Чтение и запись данных


Закрытие файлов



Манипуляции с буферами

Функция
Использование
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>, нужно выполнить следующие действия:


1. Подключить файл <ctype.h>, если необходимы другие мак-
ро;
2. Если <ctype.h> подключен , записать директиву #undef
для tolower и toupper;
3. Подключить <stdlib.h>.


Объявления tolower и toupper в <stdlib.h> заключены в
#ifndef-блоке и обрабатываются только в том случае, если соответ-
ствующий идентификатор (tolower и toupper) не определен.

Преобразование данных
ФУНКЦИЯ
ИСПОЛЬЗОВАНИЕ
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; здесь приводится более полное и точное
описание. Функция

printf(control,arg1,arg2))



преобразует, определяет формат и печатает свои аргументы в стандарт-
ный вывод под управлением строки 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 символов). Мы по-
местили двоеточия вокруг каждого поля для того, чтобы вы
могли видеть его протяженность.



:%10S: :HELLO, WORLD:
:%10-S: :HELLO, WORLD:
:%20S: : HELLO, WORLD:
:%-20S: :HELLO, WORLD :
:%20.10S: : HELLO, WOR:
:%-20.10S: :HELLO, WOR :
:%.10S: :HELLO, WOR:



Предостережение: 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.
Например, обращение


int i;
float x;
char name[50];
scanf("&d%f%s",&i,&x,name);



со строкой на вводе

25 54.32E-1 THOMPSON

приводит к присваиванию I значения 25,X - значения 5.432 и NAME -
строки "THOMPSON", надлежащим образом законченной символом \0. эти
три поля ввода можно разделить столькими пробелами, табуляциями и
символами новых строк, сколько вы пожелаете. Обращение



int i,
float x;
char name[50];
scanf("%2D %F %*D %2S", &I, &X, NAME);



с вводом

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>.

Предопределенные handle-ры

При выполнении программы всегда определены 5 handle-ров,
соответствующие стандартному вводу, стандартному выводу, стандар-
тным ошибкам, стандартному дополнительному потоку и стандартной
печати. Для доступа к этим 5 стандартным потокам в программе мо-
гут быть вызваны низкоуровневые функции при помощи предопределен-
ных handle-ров.

Поток
Handle-р
stdin
0
stdout
1
stderr
2
stdaux
3
stdprn
4


Эти файлы можно использовать в программах без предваритель-
ного открытия соответствующих файлов. Они автоматически открыва-
ются в начале работы программы, как показано в фрагменте малень-
кой программы, использующей функцию fileno для печати значений
файловых handle-ров, определенных потоками стандартного ввода,
вывода, ошибок, дополнительного, печати.


#include <stdio.h>
main()
{ printf ("stdin: %d\n", fileno(stdin));
printf ("stdout: %d\n", fileno(stdout));
printf ("stdaux: %d\n", fileno(stdaux));
printf ("stderr: %d\n", fileno(stderr));
printf ("stdprn: %d\n", fileno(stdprn));
}


Тогда на выходе будет следующая информация:


stdin: 0
stdout: 1
stderr: 2
stdaux: 3
stdprn: 4.


Чтение и запись данных

Две базовые функции - read и write - выполняют ввод-чтение
и вывод-запись. Аналогично потоковым функциям, операции ввода/вы-
вода начинаются с текущей позиции в файле. При выполнении опера-
ций ввода/вывода текущая позиция каждый раз корректируется (об-
новляется). Для проверки конца файла может быть использована про-
цедура eof. В случае возникновения ошибки низкоуровневыми проце-
дурами ввода/ вывода устанавливается переменная errno. Поэтому
чтобы распечатать информацию об ошибках ввода/вывода, нужно ис-
пользовать функцию perror, а для размещения данной информации в
строку - функцию strerror. Использованием функции lseek можно пе-
ремещать указатель на файл в любое место файла; следующая опера-
ция будет выполняться с установленной ранее позиции. Для опреде-
ления текущей позиции указателя на файл используется функция
tell.
Устройства (такие как консоль) не имеют указателей на файл.
Процедуры lseek и tell вырабатавают неопределенный результат, ес-
ли они используются для подобных устройств.

Закрытие файлов


Функция close закрывает открытый файл. Если программа за-
канчивает выполнение, все открытые файлы автоматически закрывают-
ся. Однако на практике рекомендуется закрывать все открытые файлы
по окончании работы с ними, так как количество одновременно отк-
рытых файлов ограничено.





Найти: на

 

 

Hosted by uCoz