Программирование CGI скриптов на C для unix - Описание функций библиотеки libc
3. Ввод и Вывод (stdio.h)
Эта глава описывает функции, которые осуществляют управление файлами и другими потоками ввода-вывода. Среди этих функций есть процедуры, которые генерируют и считывают строки в соответствии с форматом string.
Дополнительные возможности ввода-вывода зависят от операционной системы, но эти функции обеспечивают единый интерфейс.
Соответствующие описания содержатся в stdio.h.
Функции повторного вхождения этих функций используют макросы
_stdin_r(reent)
_stdout_r(reent)
_stderr_r(reent)
вместо глобальных stdin, stdout и stderr. Аргумент <[reent]>
является указателям на данные для повторного вхождения.
3.1 clearerr - очищает индикатор ошибки файла или потока
#include <stdio.h>
void clearerr(FILE *fp);
Функции stdio заводят индикатор ошибок для каждого файла, на
который указывает указатель fp, для записи туда информации об ошибках
ввода-вывода, связанных с данным файлом или потоком. Аналогично
заводится индикатор конца файла, показывающий, есть ли еще данные в
этом файле.
Используйте clearerr для сброса этих индикаторов.
Используйте ferror и feof для проверки этих индикаторов.
clearerr не возвращает никакого результата.
Стандарт ANSI требует наличия функции clearerr.
Никаких процедур ОС не требуется.
3.2 fclose - закрытие файла
#include <stdio.h>
int fclose(FILE *fp);
Если определенный fp файл или поток открыт, то fclose закрывает
его, предварительно записав все обрабатываемые данные (вызвав
fflush(fp)).
fclose возвращает 0, если он был выполнен успешно (включая случай, когда fp - NULL или не открытый файл); иначе возвращается EOF.
Стандарт ANSI требует наличия функции fclose.
Требуются процедуры ОС: close, fstat, isatty, lseek, read, sbrk, write.
3.3 feof - проверка конца файла
#include <stdio.h>
int feof(FILE *fp);
feof проверяет, был ли достигнут конец файла, на который
указывает fp.
feof возвращает 0, если конец файла еще не был достигнут, и ненулевое значение в противном случае.
Стандарт ANSI требует наличия функции feof.
Никаких процедур ОС не требуется.
3.4 ferror - проверка на возникновение ошибки ввода-вывода
#include <stdio.h>
int ferror(FILE *fp);
Функции stdio заводят индикатор ошибок для каждого файла, на
который указывает указатель fp, для записи туда информации об ошибках
ввода-вывода, связанных с данным файлом или потоком. Используйте
ferror для выяснения значения этого индикатора.
Используйте clearerr для сброса индикатора ошибки.
ferror возвращает 0 в случае отсутствия ошибок; в случае отсутствия ошибок возвращается ненулевое значение.
Стандарт ANSI требует наличия функции ferror.
Никаких процедур ОС не требуется.
3.5 fflush - очищает буфер вывода в файл
#include <stdio.h>
int fflush(FILE *fp);
Функции вывода stdio могут буферизировать вывод, для
минимизации количества лишних системных вызовов.
Используйте fflush для завершения вывода из файла или потока, определяемого fp.
Если fp равен NULL, fflush заканчивает вывод изо всех открытых файлов.
fflush возвращает 0 во всех случаях, кроме тех, когда происходят ошибки записи; в этих случаях возвращается EOF.
Стандарт ANSI требует наличия функции fflush.
Никаких процедур ОС не требуется.
3.6 fgetc - считывание знака из файла или потока
#include <stdio.h>
int fgetc(FILE *fp);
Используйте fgetc для считывания следующего знака из файла или
потока, определяемого fp. При этом fgetc сдвигает индикатор текущей
позиции файла.
Для использования макро-версии этой функции смотрите getc.
Возвращается следующий знак (читается как unsigned char и преобразовывается в int), если только не заканчиваются данные или операционная система возвращает ошибку чтения; в обоих этих случаях fgetc возвращается EOF.
Вы можете различить две ситуации возврата EOF при помощи функций ferror и feof.
Стандарт ANSI требует наличия функции fgetc.
Требуются процедуры ОС: close, fstat, isatty, lseek, read, sbrk, write.
3.7 fgetpos - записывает позицию в потоке или файле
#include <stdio.h>
int fgetpos(FILE *fp, fpos_t *pos);
Объект типа FILE может иметь "позицию", которая показывает,
какая часть файла уже была прочитана программой. Многие функции stdio
зависят от этой позиции и многие изменяют ее.
Вы можете использовать fgetpos для получения текущей позиции файла, на который указывает fp; fgetpos запишет значение, представляющие эту позицию, в *pos. Позже можно использовать это значение, возвращаясь при помощи fsetpos на эту позицию в файле.
В этой реализации fgetpos использует счетчик знаков для представления позиции в файле, это то же самое число, что возвращается ftell.
fgetpos возвращает 0 в случае успешного выполнения. Если fgetpos не выполняется, то в результате выдается 1. Ошибка происходит, если поток не поддерживает позиционирования; глобальный errno имеет в этой ситуации значение espipe.
Стандарт ANSI требует наличия функции fgetpos, но значения записываемых им величин не специфицированы, за исключением того, что они могут быть переданы в качестве аргументов для fsetpos. В конкретной реализации C ftell может выдавать результаты, отличные от записываемых fgetpos в *pos.
Никаких процедур ОС не требуется.
3.8 fgets - считывает строку знаков из файла или потока
#include <stdio.h>
char *fgets(char *buf, int n, FILE *fp);
Считывает не более n-1 знак из fp до знака новой строки. Эти
знаки, включая знак новой строки, сохраняются в buf. В конце буфера
записывается 0.
fgets возвращает переданный ей буфер, заполненный данными. Если конец файла встретился, когда какие-то данные уже были собраны, то данные возвращаются без какого-либо обозначения этого. Если никакие данные не были прочитаны, то возвращается NULL.
fgets должен заменить все вхождения gets. Отметим, что fgets возвращает все данные, в то время как gets убирает знаки новых строк, не показывая этого.
Требуются процедуры ОС: close, fstat, isatty, lseek, read, sbrk, write.
3.9 fiprintf - форматирует вывод в файл (только для целых чисел)
#include <stdio.h>
int fiprintf(FILE *fd, const char *format, ...);
fiprintf - ограниченная версия fprintf: она имеет те же
аргументы и выполняет те же операции, но не может осуществлять
операции с числами с плавающей точкой - спецификации типов `f', `g',
`g', `e' и `f' не распознаются.
fiprintf возвращает число байт в выведенной строке, не считая завершающего NULL. fiprintf заканчивает работу, если встречает конец форматируемой строки. Если встречается ошибка, то fiprintf возвращает EOF.
Стандарт ANSI не требует наличия функции fiprintf.
Требуются процедуры ОС: close, fstat, isatty, lseek, read, sbrk, write.
3.10 fopen - открывает файл
#include <stdio.h>
FILE *fopen(const char *file, const char *mode);
FILE *_fopen_r(void *reent, const char *file, const char *mode);
fopen инициализирует структуры данных, необходимых для чтения
или записи файла. Имя файла определяется строкой в file, а тип доступа
к файлу - строкой в mode.
Другая функция _fopen_r является повторно-входимым аналогом. Дополнительный аргумент reent - указатель на структуру, содержащую информацию для обеспечения повторной входимости.
Возможны три основных типа доступа: чтение, запись и добавление. *mode должен начинаться с одного из трех знаков ``r'', ``w'' или ``a'', которые означают следующие:
- `r'
Открыть файл для чтения; эта операция заканчивается неудачей, если файл не существует или операционная система не разрешает прочитать его.
- `w'
Откpыть файл для записи с начала, фактически создается новый файл. Если файл с этим именем yже сyществyет, то его содеpжимое пpопадает.
- `a'
Откpывает файл для добавления данных, то есть дописывания текста в конец файла. Когда Вы откpываете файл таким способом, все данные записываются в текyщий конец файла, использование fseek не может повлиять на это.
``rb'', таким образом, означает "чтение двоичного файла"; ``wb''- "запись двоичного файла"; ``ab'' - "дописать двоичный файл".
Для большей переносимости программ на c ``b'' допускается на всех системах, в не зависимости от того, имеет ли это значение.
Наконец, может понадобиться возможность как чтения, так и записи файла. Для этого можно добавить ``+'' к какому-либо из трех режимов. (Если добавляются и ``b'' и ``+'', то это можно делать в любом порядке: например: "rb+" эквивалентно "r+b" при использовании в качестве строки задания режима.)
Использование "r+" (или "rb+") позволяет читать и записывать в любом месте существующего файла, не уничтожая данных; "w+" (или "wb+") создает новый файл (или стиpает все данные из стаpого), что позволяет читать и записывать в любом месте этого файла; "a+" (или "ab+") позволяет считывать любое место файла, но записывать - только в конец.
fopen возвращает указатель на файл, который Вы можете использовать в других операциях с файлом, если только запрашиваемый файл может быть открыт, в этом случае выдается NULL. Если причиной ошибки была неправильная строка mode, то errno устанавливается в EINVAL.
Стандарт ANSI требует наличия функции fopen.
Требуются процедуры ОС: close, fstat, isatty, lseek, open, read, sbrk, write.
3.11 fdopen - преобразовывает открытый файл в поток
#include <stdio.h>
FILE *fdopen(int fd, const char *mode);
FILE *_fdopen_r(void *reent, int fd, const char *mode);
fdopen получает дескриптор файла типа file * из дескриптора уже
открытого файла (получаемого, например, системной процедурой `open'
или, реже, при помощи fopen). Аргумент mode имеет тоже значение, что и
в fopen.
Возвращается указатель на файл или NULL, как и для fopen.
Стандарт ANSI требует наличия функции fdopen.
3.12 fputc - записывает знак в файл или поток
#include <stdio.h>
int fputc(int ch, FILE *fp);
fputc преобразовывает аргумент ch из int в unsigned char, а
затем записывает это в файл или поток, определяемый fp.
Если файл был откpыт в pежиме добавления (или поток не поддеpживает позициониpования), то новый знак записывается в конец файла или потока. В дpyгих слyчаях новый знак записывается в соответствии с индикатоpом текyщей позиции в файле, котоpый yвеличивается на один.
Для использования макро-версии этой функции смотрите putc.
В случае успешного выполнения fputc возвращает аргумент ch. В случае ошибки выдается EOF. Выяснить тип ошибки можно при помощи ferror(fp).
Стандарт ANSI требует наличия функции fputc.
Требуются процедуры ОС: close, fstat, isatty, lseek, read, sbrk, write.
3.13 fputs - записывает строку знаков в файл или поток
#include <stdio.h>
int fputs(const char *s, FILE *fp);
fputs записывает строку s (без завершающего NULL) в файл или
поток, определенный fp.
В случае успешного выполнения выдается 0; в противном случае выдается EOF.
Стандарт ANSI требует наличия функции fputs, но не требует выдачи 0 в случае успешного выполнения, допустимо любое неотрицательное значение.
Требуются процедуры ОС: close, fstat, isatty, lseek, read, sbrk, write.
3.14 fread - чтение элементов массива из файла
#include <stdio.h>
size_t fread(void *buf, size_t size, size_t count, FILE *fp);
fread пытается скопировать из файла или потока, определенного
fp, count элементов (каждый размера size) в память, начиная с buf.
fread может скопировать меньше count элементов в случае ошибки или
конца файла.
fread также увеличивает индикатор позиции в файле на число реально считанных знаков.
В результате fread выдает количество успешно прочитанных элементов.
Стандарт ANSI требует наличия функции fread.
Требуются процедуры ОС: close, fstat, isatty, lseek, read, sbrk, write.
3.15 freopen - открытие файла с использованием существующего дескриптора
#include <stdio.h>
FILE *freopen(const char *file, const char *mode, FILE *fp);
Этот вариант fopen позволяет определять для файла особенные
дескрипторы fp (например stdin, stdout или stderr).
Если fp был связан с другим файлом или потоком, freopen закрывает это файл или поток (но игнорирует при этом все ошибки).
file и mode имеют то же значение, что и для fopen.
В случае успешного выполнения выдается аргумент fp. Если указанный файл не может быть открыт, то выдается NULL.
Стандарт ANSI требует наличия функции freopen.
Требуются процедуры ОС: close, fstat, isatty, lseek, open, read, sbrk, write.
3.16 fseek - переходит на позицию в файле
#include <stdio.h>
int fseek(FILE *fp, long offset, int whence)
Объект типа FILE может иметь "позицию", которая показывает,
какая часть файла уже была прочитана программой. Многие функции stdio
зависят от этой позиции и многие изменяют ее.
Вы можете использовать fseek для перехода на позицию в файле fp. Значение offset определяет новую позицию, одним из трех способов определяемую значением whence (определяется как макрос в stdio.h):
- seek_set
offset указывает на абсолютное место в файле (смещение относительно начала файла). offset должен быть положительным.
- seek_cur
offset указывает смещение относительно текущей позиции. offset может принимать как положительные, так и отрицательные значения.
- seek_end
offset указывает смещение относительно конца файла. offset может быть как положительным (что увеличивает размер файла), так и отрицательным.
fseek возвращает 0 в случае успешного выполнения. В противном случае возвращается EOF. Причина ошибки обозначается в errno значениями espipe (поток, на который указывает fp не поддерживает перемену позиции) и einval (неправильная позиция в файле).
Стандарт ANSI требует наличия функции fseek.
Требуются процедуры ОС: close, fstat, isatty, lseek, read, sbrk, write.
3.17 fsetpos - возвращается на позицию в потоке ил файле
#include <stdio.h>
int fsetpos(FILE *fp, const fpos_t *pos);
Объект типа FILE может иметь "позицию", которая показывает,
какая часть файла уже была прочитана программой. Многие функции stdio
зависят от этой позиции и многие изменяют ее.
fsetpos преобразовывает текущую позицию в файле, указанном fp, на предыдущую позицию *pos (которая была получена при помощи fgetpos).
Процедура fseek делает примерно тоже.
fgetpos возвращает 0 в случае успешного выполнения. В противном случае fgetpos возвращает 1. Причина ошибки обозначается в errno значениями espipe (поток, на который указывает fp не поддерживает перемену позиции) и einval (неправильная позиция в файле).
Стандарт ANSI требует наличия функции fsetpos, но не определяет структуру *pos кроме ее соответствия выдаваемым fgetpos результатам.
Требуются процедуры ОС: close, fstat, isatty, lseek, read, sbrk, write.
3.18 ftell - возвращает позицию в потоке или файле
#include <stdio.h>
long ftell(FILE *fp);
Объект типа FILE может иметь "позицию", которая показывает,
какая часть файла уже была прочитана программой. Многие функции stdio
зависят от этой позиции и многие изменяют ее.
В результате ftell выдает текущую позицию в файле, указанном fp. Сохраненный результат может потом использоваться с fseek для возвращения на эту позицию.
В данной реализации ftell просто использует счетчик знаков для представления позиции в файле; это то же число, что будет выдано fgetpos.
ftell возвращает позицию в файле, если это возможно. В противном случае возвращается -1l. Ошибка происходит, если поток не поддерживает позиционирование; глобальный errno обозначает эту ситуацию при помощи значения espipe.
Стандарт ANSI требует наличия функции ftell, но значение ее результата (в случае успешного выполнения) не специфицировано, кроме требования соответствия формату аргумента fseek. В некоторых реализациях c ftell может возвращать результат, отличный от записываемого fgetpos.
Никаких процедур ОС не требуется.
3.19 fwrite - запись элементов массива
#include <stdio.h>
size_t fwrite(const void *buf, size_t size, size_t count, FILE *fp);
fwrite пытается скопировать, начиная с buf, count элементов
(каждый pазмеpа size) в файл или поток, указанный fp. fwrite может
скопировать меньше count элементов в случае ошибки.
fwrite также сдвигает вперед индикатор позиции в файле (если он есть) на число реально записанных знаков.
Если fwrite выполняется успешно, то выдается аргумент count. В других случаях выдается число элементов, полностью скопированных в файл.
Стандарт ANSI требует наличия функции fwrite.
Требуются процедуры ОС: close, fstat, isatty, lseek, read, sbrk, write.
3.20 getc - считывание знака (макро)
#include <stdio.h>
int getc(FILE *fp);
getc - это макро, определенное в stdio.h. getc считывает
следующий знак из файла или потока, определенного fp. getc сдвигает
индикатор текущей позиции.
Для использования подпрограммы вместо макро смотрите fgetc.
Выдается следующий знак (читается как unsigned char и преобразовывается в int), если только не заканчиваются данные или операционная система сообщает об ошибке чтения; в обоих случаях getc возвращает EOF.
Эти ситуации можно различить используя функции ferror и feof.
Стандарт ANSI требует наличия функции getc; он предполагает, но не требует, чтобы функция getc была введена как макро. Реализация getc как макро может использовать один и тот же аргумент несколько раз; однако в переносимых программах лучше не использовать выражения, вызывающие побочные эффекты, как аргументы getc.
Требуются процедуры ОС: close, fstat, isatty, lseek, read, sbrk, write.
3.21 getchar - чтение знака (макро)
#include <stdio.h>
int getchar(void);
int _getchar_r(void *reent);
getchar - это макро, определенное в stdio.h. getchar считывает
следующий знак из стандартного входного потока, определенного fp.
getchar сдвигает индикатор текущей позиции.
Другая функция _getchar_r является повторно-входимым аналогом. Дополнительный аргумент reent - указатель на структуру, содержащую информацию для обеспечения повторной входимости.
Выдается следующий знак (читается как unsigned char и преобразовывается в int), если только не кончились данные или операционная система сообщает об ошибке чтения; в обоих случаях getchar возвращает EOF.
Эти ситуации можно различить при помощи ferror(stdin) и feof(stdin).
Стандарт ANSI требует наличия функции getchar; он предполагает, но не требует, чтобы функция getchar была введена как макро.
Требуются процедуры ОС: close, fstat, isatty, lseek, read, sbrk, write.
3.22 gets - считывает строку знаков (устаревшее, взамен используйте fgets)
#include <stdio.h>
char *gets(char *buf);
char *_gets_r(void *reent, char *buf);
Считывает знаки из стандартного ввода до знака новой строки.
Знаки до новой строки сохраняются в buf. Знак новой строки опускается,
а буфер заканчивается 0.
Это опасная функция, так как нет способа проверить наличие места в buf. Один из способов атаки internet worm в 1988 использовал это для переполнения буфера в стеке finger-демона и перезаписывал адрес возврата, вызывая выполнение демоном полученного после соединения кода.
Другая функция _gets_r является повторно-входимым аналогом. Дополнительный аргумент reent - указатель на структуру, содержащую информацию для обеспечения повторной входимости.
gets возвращает переданный буфер, заполненный данными. Если конец файла встречается в момент, когда некоторые данные уже записаны, то данные возвращаются без каких-либо признаков этого. Если конец файла встретился пи пустом буфере, то возвращается NULL.
Требуются процедуры ОС: close, fstat, isatty, lseek, read, sbrk, write.
3.23 iprintf - записывает форматированный вывод (только для целых чисел)
#include <stdio.h>
int iprintf(const char *format, ...);
iprintf - ограниченная версия printf: она имеет те же аргументы
и выполняет те же операции, но не может осуществлять операции с
числами с плавающей точкой - спецификации типов `f', `g', `g', `e' и
`f' не распознаются.
iprintf возвращает число байт в выведенной строке, не считая завершающего NULL. iprintf заканчивает работу, если встречает конец форматируемой строки. Если встречается ошибка, то iprintf возвращает EOF.
Стандарт ANSI не требует наличия функции iprintf.
Требуются процедуры ОС: close, fstat, isatty, lseek, read, sbrk, write.
3.24 mktemp, mkstemp - генерирует не используемое имя файла
#include <stdio.h>
char *mktemp(char *path);
int mkstemp(char *path);
char *_mktemp_r(void *reent, char *path);
int *_mkstemp_r(void *reent, char *path);
mktemp и mkstemp пытаются создать имя, не используемое для
существующего файла. mkstemp создает файл и открывает его для чтения и
для записи; mktemp просто выдает имя файла.
Строка path задает начало имени файла. Она должна быть пpавильным именем файла (возможно включающим пyть), заканчивающимся на несколько знаков ``x''. Созданное имя бyдет начинаться на этy стpокy, а оставшиеся ``x'' бyдyт заменены какой-либо комбинацией цифp и бyкв.
Другие функции _mktemp_r и _mkstemp_r являются повторно-входимыми аналогами. Дополнительный аргумент reent является указателем на структуру, содержащую информацию для обеспечения повторной входимости.
mktemp возвращает указатель path на модифицированную строку, представляющую не используемое имя файла, если оно было сгенерировано, в противном случае возвращается NULL.
mkstemp возвращает дескриптор нового созданного файла, если возможно сгенерировать имя несуществующего файла, в противном случае возвращается -1.
Стандарт ANSI C не требует ни mktemp, ни mkstemp; System V Interface Definition (определение интерфейса System V) издание 2 требует наличие mktemp.
Требуются процедуры ОС: getpid, open, stat.
3.25 perror - печатает сообщение об ошибке в стандартный поток ошибок.
#include <stdio.h>
void perror(char *prefix);
void _perror_r(void *reent, char *prefix);
perror печатает (в стандартный поток ошибок) сообщение об
ошибке, соответствующее текущему значению глобальной переменной errno.
Если NULL не передан как значение аргумента prefix, то сообщение об
ошибке будет записано в строку, начинающуюся в prefix, которая будет
оканчиваться двоеточием и пробелом (`: '). Остальная часть сообщения
об ошибке - одна из строк, описанных для strerror.
Другая функция _perror_r является повторно-входимым аналогом. Дополнительный аргумент reent - указатель на структуру, содержащую информацию для обеспечения повторной входимости.
perror не возвращает никакого результата.
Стандарт ANSI требует наличия функции perror, но выводимые строки отличаются в зависимости от реализации.
Требуются процедуры ОС: close, fstat, isatty, lseek, read, sbrk, write.
3.26 putc - записывает знак (макро)
#include <stdio.h>
int putc(int ch, FILE *fp);
putc - это макро, определенное в stdio.h. putc записывает
аргумент ch в файл или поток, определенный fp, после преобразования
его из int в unsigned char.
Если файл был открыт в режиме добавления (или поток не поддерживает позиционирования), то новый знак записывается в конец файла или потока. в противном случае новый знак записывается в соответствии с текущим значением индикатора позиции, который увеличивается при этом на один.
Реализацию этого макро как процедуры смотрите в fputc.
В случае успешного выполнения putc возвращает свой аргумент ch. В случае ошибки выдается EOF. Для определения наличия ошибок можно использовать ferror(fp).
Стандарт ANSI требует наличия функции putc; это предполагает, но не требует, putc был реализован как макро. Стандарт разрешает макро-реализациям putc использовать аргумент fp более одного раза; тем не менее, для переносимых программ, не следует использовать выражения, выполняющие какие-либо дpyгие действия, в качестве этого аргумента.
Требуются процедуры ОС: close, fstat, isatty, lseek, read, sbrk, write.
3.27 putchar - записывает знак (макро)
#include <stdio.h>
int putchar(int ch);
int _putchar_r(void *reent, int ch);
putchar - это макро, определенное в stdio.h. putchar записывает
свой аргумент в стандартный поток вывода, после преобразования из int
в unsigned char.
Другая функция _putchar_r является повторно-входимым аналогом. Дополнительный аргумент reent - указатель на структуру, содержащую информацию для обеспечения повторной входимости.
В случае успешного выполнения putchar возвращает свой аргумент ch. В случае ошибки выдается EOF. Для определения наличия ошибок можно использовать ferror(stdin).
Стандарт ANSI требует наличия функции putchar; при этом предполагается, но не требуется, чтобы putchar был реализован как макро.
Требуются процедуры ОС: close, fstat, isatty, lseek, read, sbrk, write.
3.28 puts - записывает строку знаков
#include <stdio.h>
int puts(const char *s);
int _puts_r(void *reent, const char *s);
puts записывает строку в s (которая оканчивается знаком новой
строки, вместо NULL) в стандартный выходной поток.
Другая функция _puts_r является повторно-входимым аналогом. Дополнительный аргумент reent - указатель на структуру, содержащую информацию для обеспечения повторной входимости.
В случае успешного выполнения выдается 0; в противном случае выдается EOF.
Стандарт ANSI требует наличия функции puts, но не определяет, что в случае успеха результат должен быть нулем, допускается любое неотрицательное значение.
Требуются процедуры ОС: close, fstat, isatty, lseek, read, sbrk, write.
3.29 remove - удаление имени файла
#include <stdio.h>
int remove(char *filename);
int _remove_r(void *reent, char *filename);
remove уничтожает связь с указанным в строке filename именем
файла и представляемым ею файлом. Использовав remove с конкpетным
именем файла, впоследствии нельзя откpыть файл с этим именем.
В этой pеализации remove можно использовать для откpытого файла и это не бyдет ошибкой; каждый сyществyющий дескриптор бyдет пpодолжать иметь достyп к данным этого файла, до тех поp, пока использyющая его пpогpамма не закpоет этот файл.
Другая функция _remove_r является повторно-входимым аналогом. Дополнительный аргумент reent - указатель на структуру, содержащую информацию для обеспечения повторной входимости.
remove возвращает 0 в случае успешного выполнения и -1 в противном случае.
Стандарт ANSI требует наличия функции remove, но определяет только ненулевой результат в случае ошибки при выполнении. Поведение remove в случае открытого файла может различаться в зависимости от реализации.
Требуется процедура ОС unlink.
3.30 rename - переименование файла
#include <stdio.h>
int rename(const char *old, const char *new);
int _rename_r(void *reent, const char *old, const char *new);
rename устанавливает новое имя файла (строка в new) для файла с
именем *old. После успешного выполнения rename файл больше не доступен
по имени *old.
В противном случае с файлом с именем *old ничего не происходит. Ошибки выполнения зависят от опеpационной системы.
Другая функция _rename_r является повторно-входимым аналогом. Дополнительный аргумент reent - указатель на структуру, содержащую информацию для обеспечения повторной входимости.
В pезyльтате выдается 0 (в случае успешного выполнения) или -1 (когда файл не может быть пеpеименован).
Стандарт ANSI требует наличия функции rename, но опpеделяет только ненyлевой pезyльтат в слyчае ошибки. Если *new является именем существующего файла, то обработка этого зависит от реализации.
Требуются процедуры ОС: link, unlink.
3.31 rewind - переинициализирует файл или поток
#include <stdio.h>
void rewind(FILE *fp);
rewind возвращает индикатор позиции (если есть) в файле или
потоке, определяемом fp в начало. Это также сбрасывает индикатор
ошибки и прекращает весь не законченный вывод.
rewind не возвpащает никакого pезyльтата.
Стандарт ANSI требует наличия функции rewind.
Никаких процедур ОС не требуется.
3.32 setbuf - определяет полную буферизацию для файла или потока
#include <stdio.h>
void setbuf(FILE *fp, char *buf);
setbuf определяет, что вывод в файл или поток, определенный fp,
должен быть полностью буферизован. Весь вывод в этот файл будет идти
через буфер (размера bufsiz, определенного в stdio.h). Вывод будет
передаваться операционной системе только в случае заполнения буфера,
или в случае операции ввода.
Указатель на другой буфер может быть передан при помощи аргумента buf. Он должен иметь pазмеp bufsiz. Передача NULL в качестве значения buf показывает, что setbuf должен сам выделить буфер.
Предупреждение: setbuf нельзя использовать после операций с файлами, отличными от открытия.
Если передается не-NULL buf, то указываемая область памяти должна быть доступна до самого закрытия потока, определяемого fp.
setbuf не возвpащает никакого pезyльтата.
Как ANSI C, так и System V Interface Definition (выпуск 2) включают в себя setbuf. Тем не менее, значения указателя буфера NULL в них различаются: SVID выпуск 2 определяет, что указатель буфера NULL означает небуферизованный вывод. Для максимальной переносимости программ избегайте использования NULL как указателя буфера.
Требуются процедуры ОС: close, fstat, isatty, lseek, read, sbrk, write.
3.33 setvbuf - определяет способ буферизации файла или потока
#include <stdio.h>
int setvbuf(FILE *fp, char *buf,
int mode, size_t size);
setvbuf определяет способ буферизации файла или потока,
определяемого fp, используя одно из следующих значений (из stdio.h) в
качестве аргумента mode:
- _ionbf
Не использовать буфер; передавать вывод прямо операционной системе для файла или потока, определенного fp.
- _iofbf
Использовать полную буферизацию вывода: вывод передается операционной системе только в случае заполнения буфера или операции ввода.
- _iolbf
Использовать построчную буферизацию: передавать вывод операционной системе при каждом знаке новой строки, также как в случае заполнения буфера или операции ввода.
Пpедyпpеждение: setvbuf нельзя использовать после операций с файлами, отличными от открытия.
Если передается не-NULL buf, то указываемая область памяти должна быть доступна до самого закрытия потока, определяемого fp.
В слyчае yспешного выполнения выдается 0, в пpотивном слyчае выдается EOF (непpавильный mode или size может вызвать ошибкy).
Как ANSI C, так и System V Interface Definition (выпуск 2) включают в себя setvbuf. Тем не менее, значения указателя буфера NULL в них различаются: SVID выпуск 2 определяет, что указатель буфера NULL означает небуферизованный вывод. Для максимальной переносимости программ избегайте использования NULL как указателя буфера.
Обе спецификации требуют ненулевого результата в случае ошибки.
Требуются процедуры ОС: close, fstat, isatty, lseek, read, sbrk, write.
3.34 siprintf - записывает форматированный вывод (только для целых чисел)
#include <stdio.h>
int siprintf(char *str, const char *format [, arg, ...]);
siprintf - ограниченная версия sprintf: она имеет те же
аргументы и поведение, за исключением невозможности форматирования при
наличии плавающей точки: спецификации типов f, g, g, e и f не
распознаются.
siprintf возвращает число байт в выведенной строке, не считая завершающего NULL. siprintf заканчивает работу, если встречает конец форматируемой строки.
Стандарт ANSI не требует наличия функции siprintf.
Требуются процедуры ОС: close, fstat, isatty, lseek, read, sbrk, write.
3.35 printf, fprintf, sprintf - форматируют вывод
#include <stdio.h>
int printf(const char *format [, arg, ...]);
int fprintf(FILE *fd, const char *format [, arg, ...]);
int sprintf(char *str, const char *format [, arg, ...]);
printf принимает серию аргументов, применяя к каждому
определитель формата из *format, и записывает форматированные данные в
stdout, заканчивая вывод знаком NULL. Поведение printf не опpеделено в
слyчае нехватки аргументов для фоpматиpования. printf заканчивает
работу, если встречает конец форматируемой строки. Если аргументов
больше, чем требуется, то лишние аргументы игнорируются.
fprintf и sprintf совпадают с printf, за исключением направления форматированного вывода: fprintf выводит в заданный файл fd, а sprintf сохраняет вывод массиве знаков str. Для sprintf обработка переполнения *str не определена. format - указатель на строку знаков, содержащую два типа объектов: обычные знаки (отличные от %), которые выводятся неизмененными и спецификации преобразования, каждая из которых начинается с %. (Для включения % в вывод можно использовать %% в форматируемой строке.) Спецификации преобразования имеют следующую форму:
%[flags][width][.prec][size][type]
Поля спецификации преобразования имеют следующие значения:
- flags
необязательная последовательность знаков, управляющих
расположением вывода, знаками чисел, десятичными точками,
завершающими нулями, восьмеричными и шестнадцатиричными
префиксами. Знаками флагов являются минус (-), плюс (+), пробел,
ноль (0) и решетка (#). Они могут быть скомбинированы
произвольным образом.
- -
Преобразованная стpока сдвигается влево, добавляясь спpава пpопyсками. Если этот флаг не использyется, то выводимая стpока сдвигается впpаво, дополняясь пpопyсками слева.
- +
В результате преобразование со знаком (как определено при помощи type) всегда с плюса или минуса. (Если этот флаг не стоит, то положительные числа выводятся без плюса.)
- " " (пробел)
Если первый знак спецификации преобразования не является плюсом или минусом, или результат преобразования со знаком не имеет его, то результат начинается с пробела. Если флаг пробел ( ) и флаг плюс (+) появляются одновременно, то пробел игнорируется.
- 0
Если знаком type является d, i, o, u, x, X, e, E, f, g или G, то впереди идущие нули используются для добавления до нужной ширины поля, (в соответствии со всеми дpyгими настpойками); пpобелы для этого не использyются. Если ноль (0) и минус (-) указываются одновременно, то флаг ноль игнорируется. Для преобразований d, i, o, u, x и X, если определена точность prec, то флаг ноль (0) игнорируется. При этом 0 интерпретируется как флаг, а не как начало ширины поля.
- #
Результат должен быть преобразован в альтернативную форму записи, в соответствии со следующим знаком:
- 0
увеличить точность, чтобы первая цифра результата была нулем.
- x
ненулевой результат будет иметь префикс 0x.
- X
ненулевой результат будет иметь префикс 0x.
- e, E или f
Результат всегда будет содержать десятичную точку, даже если за ней не следуют десятичные знаки. (Обычно десятичная точка появляется только в том случае, когда за ней следуют десятичные знаки.) Нули в конце убираются.
- g или G
тоже самое, что e или E, но нули на конце остаются.
- все остальные знаки
их обработка не определена.
- width width - необязательный параметр, задающий минимальную ширину поля. Эта величина может быть прямо задана десятичным числом, или может быть задана косвенно при помощи астерикса (*), в этом случае аргумент типа int используется как ширина поля. Отрицательная ширина поля не поддерживается, если происходит попытка задать отрицательную ширину поля, то она интерпретируется как флаг минус (-), за которым следует положительная ширина поля.
- prec необязательный параметр; если он указан, то он начинается с `.' (период). Это поле задает максимальное число выводимых знаков и минимальное число знаков в выводимом целом числе для преобразований с type d, i, o, u, x и X; максимальное число значащих цифр для преобразований g и G; или число знаков после десятичной точки для e, E, и f. Эта величина может быть прямо задана десятичным числом, или может быть задана косвенно при помощи астерикса (*), в этом случае аргумент типа int используется как точность. Задание отрицательной точности эквивалентно отсутствию этого аргумента. Если задан только период, то точность полагается равной нулю. Если точность задается с другими type, то обработка этой ситуации не определена.
- size h, l и L - необязательные знаки размеров, которые оказывают влияние несмотря на стандартную обработку printf аргументов данного типа. h определяет применение следующх type d, i, o, u, x или X к short или unsigned short. h также устанавливает применение следующего type n к указателю на short. Аналогично, l определяет применение следующх type d, i, o, u, x или X к long или unsigned long. l также устанавливает применение следующего type n к указателю на long. Если h или l появляются вместе с дpyгой опцией преобразования, то обpаботка этой ситyации не опpеделена. L определяет применение следующх type e, E, f, g или G к long double. Если L появляется вместе с дpyой опцией преобразования, то обpаботка этой ситyации не опpеделена.
- type
type определяет тип осуществляемого преобразования, в
соответствии со следующей таблицей:
- %
выводит знак процента (%)
- c
выводит arg как простой знак
- s
выводит знаки до достижения точности или NULL; считывает указатель на строку
- d
выводит десятичное целое со знаком; считывает int (тоже само что i)
- i
выводит десятичное целое со знаком; считывает int (тоже само что d)
- o
выводит восьмеричное целое со знаком; считывает int
- u
выводит десятичное целое без знака; считывает int
- x
выводит шестнадцатичное целое без знака (используя abcdef как цифры послу 9); считывает int
- X
выводит шестнадцатичное целое без знака (используя ABCDEF как цифры послу 9); считывает int
- f
выводит значение со знаком в виде [-]9999.9999; считывает число с плавающей точкой
- e
выводит значение со знаком в виде [-]9.9999e[+|-]999; считывает число с плавающей точкой
- E
выводит тоже самое, что и при e, но использует E для записи экспоненты; считывает число с плавающей точкой
- g
выводит значение со знаком как в случае f или e, в зависимости от заданного значения и точности - нули на конце и десятичные точки печатаются только в случая необходимости; считывает число с плавающей точкой
- G
выводит тоже самое, что и при g, но использует E для записи экспоненты; считывает число с плавающей точкой
- n
сохраняет (в том же объекте) количество выведенных знаков; считывает указатель на int
- p
выводит указатель в формате данной реализации. Эта реализация рассматривает его как unsigned long (тоже что и Lu).
Стандаpт ANSI C опpеделяет, что должен поддеpживаться фоpматиpованный вывод до 509 знаков.
Требуются процедуры ОС: close, fstat, isatty, lseek, read, sbrk, write.
3.36 scanf, fscanf, sscanf - считывает и форматирует ввод
#include <stdio.h>
int scanf(const char *format [, arg, ...]);
int fscanf(FILE *fd, const char *format [, arg, ...]);
int sscanf(const char *str, const char *format [, arg, ...]);
scanf считывает последовательность входных полей из
стандартного ввода, один знак за раз. Каждое поле интерпретируется в
соответствии с переданным определителем формата в форматированной
строке *format. scanf сохраняет обработанный ввод из каждого поля по
адресу, переданному, как аргумент после format. Должно быть задано
столько же определителей формата и адресов, сколько и вводимых полей.
Должно быть передано достаточно адресов для данного формата; в противном случае результат непредсказуем и может иметь катастрофические последствия. Лишние переданные адреса игнорируются.
scanf часто выдает непредвиденные результаты, если ввод отличается от ожидаемого шаблона. Поскольку комбинация gets или fgets, за которыми следует sscanf проста и надежна, это наиболее предпочтительный способ, чтобы программа синхронизировала ввод и конец строки.
fscanf и sscanf совпадают со scanf, за исключением источника ввода: fscanf считывает данные из файла, а sscanf - из строки.
Строка *format - последовательность знаков, состоящая из нуля или более директив. Директивы состоят из одного или более знаков пропуска, других знаков и определителей формата.
Знаками пропуска являются пробел ( ), tab (\t) и новая строка (\n). Когда scanf встречает знаки пропуска в строке форматов, то он считывает их (но не сохраняет) до первого отличного от пропуска знака.
Отличными от пропуска знаками являются все остальные знаки ASCII, за исключением процента (%). Когда scanf встречает отличный от пропуска знак в строке форматов, то он считывает его, но не считывает выравнивающие пропуски.
Определители формата указывают scanf считывать и пpеобpазовывать знаки из вводимых полей в определенные типы величин, и сохраняет их по переданным адресам.
Остающиеся пропуски остаются непрочтенными, если только они не соответствуют в точности строке форматов.
Определитель формата должен начинаться с процента (%) и иметь следующую форму:
%[*][width][size]type
Каждое поля спецификации начинается с процента (%). Другие поля
следующие:
- необязательный знак; прекращает интерпретацию и определение этого вводимого поля
- width необязательная максимальная ширина поля: десятичное число, которое устанавливает максимальное число знаков, считываемых при преобразовании текущего вводимого поля. Если в вводимом поле меньше width знаков, то scanf считывает все знаки поля, а потом обрабатывает следующие поля и их спецификации. Если пpопyск или непреобразуемый знак встpечаются пеpед width, то все знаки до него считываются, пpеобразуются и сохpаняются. Затем scanf обpабатывает следyющий опpеделитель фоpмата.
- size
h, l и L - необязательные параметры, которые переопределяют
стандартный метод обработки scanf данных соответствующего
аргументам типа.
Модификатор Тип (типы) h d, i, o, u, x преобразовывает ввод в short, сохраняет в объектах типа short h D, I, O, U, X никакого эффекта e, f, c, s, n, p l d, i, o, u, x преобразовывает ввод в long, сохраняет в объектах типа long l e, f, g преобразовывает ввод в double сохраняет в объектах типа double l D, I, O, U, X никакого эффекта c, s, n, p L d, i, o, u, x преобразовывает в long double, сохраняет в объектах типа long double L все остальные никакого эффекта
- type
Знак, определяющий тип преобразования, осуществляемого scanf. Вот
таблица этих знаков:
- %
Никакого преобразования не делается; знак пpоцента (%) сохpаняется.
- c
Считывает один знак. Соответствующий arg: (char *arg).
- s
Считывает строку знаков в переданный массив. Соответствующий arg: (char arg[]).
- [pattern]
Считывает непустую строку знаков в область памяти, начинающуюся с arg. Эта область должна быть достаточно большой для записи считываемой последовательности и автоматически добавляющегося знака NULL. (pattern обсуждается в параграфе, идущем сразу после этой таблицы). Соответствующий arg: (char *arg).
- d
Считывает десятичное целое в соответствующий arg: (int *arg).
- D
Считывает десятичное целое в соответствующий arg: (long *arg).
- o
Считывает восьмеричное целое в соответствующий arg: (int *arg).
- O
Считывает восьмеричное целое в соответствующий arg: (long *arg).
- u
Считывает десятичное целое без знака в соответствующий arg: (unsigned int *arg).
- U
Считывает десятичное целое без знака в соответствующий arg: (unsigned long *arg).
- x, X
Считывает шестнадцатиричное целое в соответствующий arg: (int *arg).
- e, f, g
Считывает число с плавающей точкой в соответствующий arg: (float *arg).
- E, F, G
Считывает число с плавающей точкой в соответствующий arg: (double *arg).
- i
Считывает десятичное, восьмеричное или шестнадцатиричное целое в соответствующий arg: (int *arg).
- i
Считывает десятичное, восьмеричное или шестнадцатиричное целое в соответствующий arg: (long *arg).
- n
сохpаняет число считанных знаков в соответствyющий arg: (int *arg).
- p
Сохpаняет считанный yказатель. ANSI C не опpеделяет детали pеализации; в этой реализации %p обрабатывается также, как и %u. Соответствующий arg: (void **arg).
- %[abcd]
строки, содержащие только a, b, c и d.
- %[^abcd]
строки, содержащие все знаки кроме a, b, c и d
- %[A-DW-Z]
строки, содержащие A, B, C, D, W, X, Y, Z
- %[z-a]
строки, содержащие знаки z, - и a
[+/-] ddddd[.]ddd [E|e[+|-]ddd]
где объекты в квадратных скобках необязательны, а ddd
представляет десятичные, восьмеричное или шестнадцатиричные
цифры.
scanf возвращает число успешно введенных полей, преобразованных и сохраненных; возвращаемое значение не учитывает несохраненных считанных полей.
Если scanf пытается пpочитать конец файла, то возвpащается значение EOF.
Если ни одно поле не было сохpанено, то возвpащается 0.
scanf может прекратить считывание поля до достижения конечного знака поля или может целиком закончить работу.
scanf прекращает считывание и переходит к следующему полю (если оно есть) в одной из следующих ситуаций:
- Знак подавления присваивания (*) появляется после % как определитель формата; текущее вводимое поле считывается, но не сохраняется.
- Знаки width уже были считаны (width - определитель ширины, положительное десятичное целое).
- Следующий знак не может быть преобразован в данном формате (например, если Z считывается при десятичном формате.
- Следующий знак не является допустимым знаком в вводимом поле.
scanf заканчивает работу при следующих обстоятельствах:
- Следующий знак в вводимом поле несовместим с ссответствующим отличным от пропуска знаком в строке форматов.
- Следующий знак в вводимомом поле - EOF.
- Строка форматов кончилась.
Стандарт ANSI требует наличия функции scanf.
Требуются процедуры ОС close, fstat, isatty, lseek, read, sbrk, write.
3.37 tmpfile - создает временный файл
#include <stdio.h>
FILE *tmpfile(void);
FILE *_tmpfile_r(void *reent);
Создает временный файл (файл, который будет автоматически
удален), используя имя, созданное tmpnam. Временный файл открывается в
режиме wb+, разрешающем чтение и запись в любом месте как в двоичном
файле (без всяких преобразований, которые операционная система может
производить над текстовыми файлами.
Другая функция _tmpfile_r является повторно-входимым аналогом. Дополнительный аргумент reent - указатель на структуру, содержащую информацию для обеспечения повторной входимости.
tmpfile обычно возвращает a yказатель на временный файл. Если такой файл не может быть создан, то выдается NULL, и в errno записывается причина ошибки.
Как ANSI C, так и System V Interface Definition (выпуск 2) требуют наличия tmpfile.
Требуются процедуры ОС close, fstat, getpid, isatty, lseek, open, read, sbrk, write.
Для работы tmpfile требуетcя глобальный yказатель environ.
3.38 tmpnam, tempnam - имя временного файла
#include <stdio.h>
char *tmpnam(char *s);
char *tempnam(char *dir, char *pfx);
char *_tmpnam_r(void *reent, char *s);
char *_tempnam_r(void *reent, char *dir, char *pfx);
Каждая из этих функций выдает имя временного файла. Получаемое
имя гарантировано не является именем другого файла (если количество
вызовов этих функций не превосходит TMP_MAX).
tmpnam создает имена файлов при помощи значения P_tmpdir (определенного в stdio.h), используя его как начало названия пути к временному файлу.
Аргумент tmpnam s задает область памяти для создания имени временного файла; если вызывается tmpnam(NULL), то используется внутренний статический буфер.
tempnam позволяет контролировать создание имен временных файлов: аргумент dir путь к директории для временных файлов, а аргумент pfx определяет префикс для базового имени файла.
Если dir равен NULL, то tempnam пытается использовать значение переменной среды TMPDIR; если такого значения нет, то tempnam использует значение P_tmpdir (определенное в stdio.h).
Если не требуется задавать префикс базового имени временных файлов, то NULL может быть передан tempnam в качестве аргумента pfx.
Другие функции _tmpnam_r и _tempnam_r являются повторно входимыми аналогами tmpnam и tempnam соответственно. Дополнительный аргумент reent - указатель на структуру, содержащую информацию для обеспечения повторной входимости.
Полyченные имена могyт слyжить в качестве имен вpеменных файлов, но сами по себе не делают файл вpеменным. Файлы с этими именами должны быть yдалены, когда они больше не нyжны.
Если область данных s пеpедана tmpnam, то там должно быть достаточно места для по кpайней меpе L_tmpnam элементов типа char.
Как tmpnam, так и tempnam возвpащают yказатель на созданное имя.
Стандарт ANSI требует наличия функции tmpnam, но не определяет использование P_tmpdir. System V Interface Definition (выпуск 2) требует как tmpnam, так и tempnam.
Требуются процедуры ОС close, fstat, getpid, isatty, lseek, open, read, sbrk, write.
Требуется глобальный yказатель environ.
3.39 vprintf, vfprintf, vsprintf - форматируют список аргументов
#include <stdio.h>
#include <stdarg.h>
int vprintf(const char *fmt, va_list list);
int vfprintf(FILE *fp, const char *fmt, va_list list);
int vsprintf(char *str, const char *fmt, va_list list);
int _vprintf_r(void *reent, const char *fmt, va_list list);
int _vfprintf_r(void *reent, FILE *fp, const char *fmt, va_list list);
int _vsprintf_r(void *reent, char *str, const char *fmt, va_list list);
vprintf, vfprintf и vsprintf являются вариантами printf,
fprintf и sprintf соответственно. Они отличаются только возможностью
передачи им списка аргументов как объект va_list (инициализируемый
va_start) вместо передачи как переменного числа аргументов.
Возвращаемые значения совпадают с возвращаемыми значениями соответствующих функций: vsprintf возвращает число байт в выводимой строке, за исключением завершающего NULL, vprintf и vfprintf возвращают число переданных знаков. В случае ошибки vprintf и vfprintf возвращают EOF. Никаких ошибок не выдает vsprintf.
Стандарт ANSI требует наличия всех трех функции.
Требуются процедуры ОС close, fstat, isatty, lseek, read, sbrk, write.