Основы программирования в Linux - Страница 55
Функции семейства
scanfEOFerrnoФункция
scanf□ традиционно их реализации полны ошибок;
□ в использовании эти функции не гибки;
□ они могут привести к созданию программного кода, в котором трудно решить, что подвергать синтаксическому анализу.
В качестве альтернативы попытайтесь применять другие функции, такие как
freadfgetsДругие потоковые функции
В библиотеке stdio существует ряд других функций, использующих потоки как параметры или стандартные потоки
stdinstdoutstderr□
fgetpos□
fsetpos□
ftell□
rewind□
freopen□
setvbuf□
removeunlinkpathrmdirЭти библиотечные функции описаны на страницах интерактивного справочного руководства в разделе 3.
Вы можете использовать функции обработки файловых потоков для повторной реализации с их помощью программы копирования файлов. Взгляните на программу copy_stdio.c в упражнении 3.3.
Эта программа очень похожа на предыдущие версии, но посимвольное копирование выполняется с помощью вызовов функций, заданных в файле stdio.h:
#include <stdio.h>#include <stdlib.h>int main() { int c; FILE *in, *out; in = fopen("file.in", "r"); out = fopen("file.out", "w"); while((c = fgetc(in)) != EOF) fputc(c, out); exit(0);}Выполнив эту программу, как прежде, вы получите:
$ TIMEFORMAT="" time ./copy_stdio0.06user 0.02system 0:00.11elapsed 81%CPUКак это работает
На этот раз программа выполняется 0,11 с, не так быстро, как низкоуровневая блочная версия, но значительно быстрее другой посимвольной версии. Это произошло потому, что библиотека stdio поддерживает внутренний буфер в структуре
FILEОшибки потока
Для обозначения ошибок многие функции библиотеки stdio применяют значения за пределами допустимых, например, пустые указатели или константу
EOFerrno#include <errno.h>extern int errno;Имейте в виду, что многие функции могут изменять значение
errnofprintferrnoВы можете также запросить состояние файлового потока, чтобы выяснить, возникла ли ошибка или достигнут конец файла.
#include <stdio.h>int ferror(FILE *stream);int feof(FILE *stream);void clearerr(FILE *stream);Функция
ferrorФункция
feofif (feof(some_stream)) /* Мы в конце */Функция
clearerrstreamПотоки и дескрипторы файлов
Каждый файловый поток ассоциирован с низкоуровневым дескриптором файла. Вы можете смешивать операции низкоуровневого ввода/вывода с высокоуровневыми потоковыми операциями, но это, как правило, неразумно, потому что трудно предсказать эффект от применения буферизации.
#include <stdio.h>int fileno(FILE *stream);FILE *fdopen(int fildes, const char *mode);Вы можете определить, какой низкоуровневый дескриптор файла применяется для файлового потока, вызвав функцию
filenofstat