Студопедия

КАТЕГОРИИ:


Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748)

Файлы. Потоковый ввод-вывод




Работа с файловой системой и файлами - одна из базовых тем программирования. Мы рассмотрим файловый ввод-вывод с использованием потоков (стандартный ввод-вывод), т. е. нам понадобится заголовок stdio.h. Любая ОС хранит для каждого приложения так называемую таблицу дескрипторов открытых потоков. В ней есть, по крайней мере, три элемента - стандартный поток ввода, стандартный поток вывода и стандартный поток вывода ошибок. Все эти потоки создаются при запуске приложения. В stdio.h для этих трёх потоков объявляются соответствующие макросы: stdin (standard input), stdout (standard output), stderr (standard error output). Для программ на C++ для доступа к файлам используется указатель на структуру FILE, объявленную в stdio.h. Ещё одним важным понятием является потоковый указатель (также называемый файловым указателем (следует не путать его с указателями C/C++). Этот указатель хранит некоторую позицию в потоке. При любой операции считывания или записи он передвигается далее, с помощью специальных функций можно заниматься его позиционированием. В заголовке stdio.h (стандартный ввод-вывод) также объявляется (обычно директивой define) целочисленная константа EOF, изначально означающая End Of File (конец файла), эта константа используется во многих функциях потокового ввода-вывода.

Итак, рассмотрим функции из stdio.h. Во-первых функции для открытия/закрытия потоков.

1. FILE *fopen (const char *filename, const char *mode). Функция открывает некоторый объект для потоковой работы с ним, обычно это файл. Первый параметр - нуль-строка, обозначающая ресурс потока. В разных ОС он имеет разную интерпретацию. Рассмотрим его в ОС Windows. Он может представлять собой относительный путь к файлу. При этом в качестве разделителя может выступать как прямой, так и обратный слеш (в последнем случае при записи строки не забудьте поставить 2-ой обратный слеш, т. к. обратный слеш в C и C++ используется для формирования Escape-последовательностей). Может также быть абсолютным путём (с указанием диска) или UNC-путём (с указанием двойного обратного слеша, имени компьютера в сети и имя ресурса, например: "\\\\COMP1\\SharedDocs\\MyDoc.txt"). Наконец таки может быть задан порт ввода-вывода, вроде "COM1" или "LPT1". Замечу, что максимальная для данной среды и данного компилятора длина строки filename доступна в препроцессорной константе FILENAME_MAX, также объявленной в stdio.h. Теперь о втором параметре, он задаёт режим доступа к открываемому объекту. Во-первых, необходимо указать в этой строке букву r, w или a. Первая открывает файл (или иной объект, в дальнейшем буду писать просто файл, т. к. этот случай наиболее используем) для чтения и устанавливает файловый указатель в начало файла. w - открытия файла для записи, если файл не существует, то он создаётся заново, в любом случае всё его содержимое очищается (если быть точным на диске оно остаётся тем же, пока вы не закроете поток или не вызовите функцию записи данных на диск). a - открытие файла для дозаписи, файловый указатель - на конец файла. К любой из трёх букв можно добавить символ +, означающий, что файл открывается как для чтения, так и для записи, так называемый режим обновления (различие между r+, w+ и a+ в позиционировании файлового указателя и очистки или нет предыдущего содержимого). Кроме того можно задать ещё букву t или b, означающие соответственно текстовый и бинарный режимы. В последнем случае содержимое файла будет читаться таким, какое оно есть, в первом же при записи \n будет записано \r\n, а при чтении наоборот. В случае ошибки возвращается NULL.

2. int fclose (FILE *stream). Закрывает поток, открытый функцией fopen, очищает буфер, выделенный для чтения-записи и освобождает память, выделенную под структуру FILE. При успешном закрытии потока функция возвращает 0, иначе - EOF (простой пример последнего: вы открываете файл на внешнем носителе для записи, пишете некоторую информацию, удаляете носитель куда подальше, fclose возвращает EOF). Замечу, что файлы обязательно надо закрывать. При записи в файл именно в этот момент осуществляется сброс информации из буфера (размер которого различен для разных систем и платформ) на диск. К тому же максимальное количество файлов, которые может открыть приложение, ограничено. Кстати это значение доступно в FOPEN_MAX.

3. FILE *freopen (const char *path, const char *mode, FILE *stream). Функция предназначена для переназначения файловому дескриптору нового значения. Замечу, что её вызов эффективней, чем fclose и затем fopen, т. к. при этом не будет лишний раз освобождаться структура FILE.

4. int fflush(FILE *stream) - форсирует сброс информации из буфера на диск.

5. FILE *tmpfile (void) - эта функция не требует никаких параметров и создаёт временный файл, доступный как для чтения, так и для записи, с флагом "wb+". Под виндой этот файл по умолчанию создаётся в корне диска, на котором расположена ваша программа. Максимально допустимое количество временных файлов ограничено TMP_MAX. Этот файл будет автоматически удалён (закрывать его не надо).

6. char *tmpnam (char *name). Функция предназначена для генерации уникальных имён для временных файлов. Подчеркну, что эта функция только генерирует имя, но не создаёт сам файл. Если строка name задана как NULL, то сгенерированное имя сохраняется в name, иначе - в внутреннем статическом буфере (его очисткой занимается операционная система или сишный рантайм). Если имя не удаётся сгенерировать, то функция возвращает NULL.

Следующий этап - запись/чтение данных. При выполнении этих функций файловый указатель автоматически перемещается к следующему элементу, именно на этом основан принцип записи/чтения.

1. fprintf и fscanf - их отличие от уже знакомых вам функций в дополнительном первом параметре - указателе на структуру файл. Замечу, что printf и scanf аналогичны fprintf(stdout,...) и fscanf(stdin,...) соответственно.

2. void perror (const char *string) - записывает в stderr строку string и описание последней ошибки. Обычно, stderr совпадает с экраном консоли. Для переназначения (например, для вывода ошибок в.log файл) используйте функцию freopen (её, кстати, также можно использовать для переназначения stdout и stdin).

3. int fgetc(FILE *stream) - читает один байт (символ) из файла и возвращает его. В случае ошибки или достижении конца файла возвращает EOF.

4. int fputc(int c, FILE *stream) - записывает байт в файл, возвращает либо записанный символ, либо EOF (в случае ошибки).

5. char *fgets(char *string, int n, FILE *stream) - считывание строки файла. При этом длина строки ограничивается: концом файла, началом новой строки, параметром n, который задаёт максимально допустимое число символов для чтения. Возвращает либо string, либо NULL (в случае ошибки).

6. int fputs (const char *string, FILE *stream) - запись строки в файл. В случае ошибки возвращает EOF. Замечу, что эта функция не добавляет автоматически символ конца строки.

7. size_t fread(void *buffer, size_t size, size_t count, FILE *stream) - чтение данных в произвольный буфер. При этом buffer - указатель на буфер (обычно массив), count - максимально допустимое количество читаемых элементов, size - размер отдельного элемента. Для определения последнего принято использовать оператор sizeof, предназначенный для вычисления количества байт занимаемым некоторым типом, например: sizeof(float).

8. size_t fwrite(const void *buffer, size_t size, size_t count, FILE *stream) - аналогичная функция для записи данных

Функции для работы с файловым указателем.

1. int feof (FILE *stream) - проверка на достижение конца файла. Возвращает не 0, если файловый указатель достиг конца файла. Рекомендуется вызывать эту функцию при каждой операцией чтения.

2. int ferror (FILE *stream) - аналогичная проверка на ошибку, вызывается как альтернатива feof, но после операций записи/чтения.

3. void clearerr (FILE *stream) - сбрасывает флаг ошибки для файлового потока (после этого ferror вернет 0).

4. int fgetpos(FILE *stream, fpos_t *pos) - считывание в переменную, на которую указывает pos текущей позиции файлового указателя. В случае ошибки возвращает не 0. fpos_t - платформо-зависимый целочисленный тип, определяемый в stdio.h.

5. int fsetpos(FILE *stream, const fpos_t *pos) - установка текущей позиции файлового указателя. В случае ошибки возвращает не 0. Устанавливаемая позиция по непонятным мне причинам передаётся в константном указателе (а не просто значение позиции), но так уж сложилось...

6. void rewind(FILE *stream) - устанавливает файловый указатель на начало файла.

7. int fseek(FILE *stream, long offset, int whence) - позиционирование указателя. offset задаёт смещение, а whence задаёт точку отсчёта, может принимать одно из 3 значений: SEEK_CUR (относительно текущей позиции файлового указателя), SEEK_SET (относительно начала файла), SEEK_END (относительно конча файла, с отсчётом в обратном направлении). В случае ошибки возвращает не 0.

 

 


 




Поделиться с друзьями:


Дата добавления: 2015-05-26; Просмотров: 479; Нарушение авторских прав?; Мы поможем в написании вашей работы!


Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет



studopedia.su - Студопедия (2013 - 2024) год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! Последнее добавление




Генерация страницы за: 0.016 сек.