Подход с использованием возможностей языка Си

Лабораторная работа №8

Тема: Исследование методов доступа к файлам данных

Цель занятия:

· Совершенствование навыков разработки программ в среде программирования MS Visual C++

· Совершенствование навыков в программировании с использованием указателей

· Исследование функций последовательного доступа к файлам

· Исследование функций прямого доступа к файлам

Время на выполнение работы: 4 часа

Программа исследований:

1. Исследование функций последовательного доступа к файлам

2. Исследование функций прямого доступа к файлам

Подготовка к выполнению работы:

1. Изучить материал настоящего руководства и рекомендованную литературу (структура программы на языке высокого уровня, алфавит и элементарные конструкции языка Си, переменные и константы, стандартные типы данных, выражения и операции в языке Си, циклы, массивы и указатели, функции, файлы данных).

2. Практически освоить порядок работы на ПЭВМ в среде программирования MS Visual C++.

Материалы для подготовки к занятию:

1. Конспект лекций

2. [1] стр. 88-91

Содержание отчета:

1. Цели исследования.

2. Программу работы.

3. Листинги программ

4. Результаты исследований

5. Выводы по каждому пункту и общий вывод.


МЕТОДИЧЕСКИЕ РЕКОМЕНДАЦИИ

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

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

В отличие от Си, в С++ файловые потоки обслуживаются с использованием потоковых классов на основе библиотек <ifsream> и <ofstream>. Рассмотрим каждый из этих способов подробнее.

Подход с использованием возможностей языка Си

В Си существует два типа потоков: текстовые (text) и двоичные (binary).

Текстовый поток - это последовательность символов. При передаче символов из потока на экран, часть из них не выводится (например, символ возврата каретки, перевода строки).

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

Прежде чем читать или записывать информацию в файл, он должен быть открыт и тем самым связан с потоком. Это можно сделать с помощью библиотечной функции fopen(). Она берет внешнее представление файла (например, c:\my_prog.txt) и связывает его с внутренним логические именем, которое используется далее в программе. Логическое имя - это указатель на требуемый файл. Его необходимо определить; делается это, например, так:

FILE *fp;

Здесь FILE - имя типа, описанное в стандартном заголовочном файле stdio.h, fp - указатель на файл. Обращение к функции fopen() в программе осуществляется выражением:

fp = fopen("спецификация_файла",

"способ_использования_файла");

Спецификация файла (т.е. имя файла и путь к нему) может, например, иметь вид: " c:\\my_prog.txt " - для файла my_prog.txt на диске с:.

Способ использования файла задается следующими символами:

· r – (от read) открыть существующий файл для чтения;

· w – (от write) создать новый файл для записи (если файл с указанным именем существует, то он будет переписан);

· а – (от add) дополнить файл (открыть существующий файл для записи информации, начиная с конца файла, или создать файл, если он не существует);

Тип файлового потока задается ключом t (текстовый) или b (бинарный). Если режим t или b не задан (например, r, w или а), то он определяется значением глобальной переменной _fmode. Если fmode=0_BINARY, то файлы открываются в двоичном режиме, а если _fmode=0_TEXT - в текстовом режиме. Константы 0_BINARY и 0_ТЕXТ определены в файле fcntl.h.

Если в результате обращения к функции fopen() возникает ошибка, то она возвращает указатель на константу NULL.

Рекомендуется использовать следующий способ открытия файла:

if ((fp = fopen("c:\\my_prog.txt", "rt")) == NULL)

{

puts("Открыть файл не удалось\n")

return 0;

}

После окончания работы с файлом он должен быть закрыт. Это делается с помощью библиотечной функции fclose(). Она имеет следующий прототип:

int fclose(FILE *fp);

При успешном завершении операции функция fclose() возвращает значение нуль. Любое другое значение говорит об ошибке.

Рассмотрим стандартные функции для работы с файлами последовательного доступа:

1. Функция putc() записывает символ в файл и имеет следующий прототип:

int putc(int с, FILE *fp);

Здесь fp - указатель на файл, возвращенный функцией fopen(), с - символ для записи (переменная с имеет тип int, но используется только младший байт). При успешном завершении putc() возвращает записанный символ, в противном случае возвращается константа EOF. Она определена в файле stdio.h и имеет значение (-1).

2. Функция getc() читает символ из файла и имеет следующий прототип:

int getc(FILE *fp);

Здесь fp - указатель на файл, возвращенный функцией fopen(). Эта функция возвращает прочитанный символ. Соответствующее значение имеет int, но старший байт равен нулю. Если достигнут конец файла, то getc возвращает значение ЕОF.

3. Функция feof() определяет конец файла при чтении двоичных данных и имеет следующий прототип:

int feof(FILE *fp);

Здесь fp - указатель на файл, возвращенный функцией fopen(). При достижении конца файла возвращается ненулевое значение, в противном случае возвращается 0.

4. Функция fputs() записывает строку символов в файл. Она отличается от функции puts() только тем, что в качестве второго параметра должен быть записан указатель на переменную файлового типа.

Например:

fputs("Ехаmple", fp);

При возникновении ошибки возвращается значение EOF.

5. Функция fgets() читает строку символов из файла. Она отличается от функции gets() тем, что в качестве второго параметра должно быть записано максимальное число вводимых символов плюс единица, а в качестве третьего - указатель на переменную файлового типа. Строка считывается целиком, если ее длина не превышает указанного числа символов, в противном случае функция возвращает только заданное число символов. Рассмотрим пример:

fgets(string, n, fp);

Функция возвращает указатель на строку string при успешном завершении и константу NULL в случае ошибки либо достижения конца файла.

Рассмотрим другие библиотечные функции, используемые для работы с файлами прямого доступа (все они описаны в файле stdio.h):

1. Функция fseek() позволяет выполнять чтение и запись с произвольным доступом и имеет следующий прототип:

int fseek(FILE *fp, long count, int access);

Здесь fp - указатель на файл, возвращенный функцией fopen(), count - номер байта относительно заданной начальной позиции, начиная с которого будет выполняться операция, access - способ задания начальной позиции.

Переменная access может принимать следующие значения:

0 - начальная позиция задана в начале файла;
1 - начальная позиция считается текущей;
2 - начальная позиция задана в конце файла.

При успешном завершении возвращается нуль, при ошибке - ненулевое значение.

2. Функция ferror() позволяет проверить правильность выполнения последней операции при работе с файлами. Имеет следующий прототип:

int ferror(FILE *fp);

В случае ошибки возвращается ненулевое значение, в противном случае возвращается нуль.

3. Функция remove() удаляет файл и имеет следующий прототип:

int remove(char *file_name);

Здесь file_name - указатель на строку со спецификацией файла. При успешном завершении возвращается нуль, в противном случае возвращается ненулевое значение.

4. Функция rewind() устанавливает указатель текущей позиции в начало файла и имеет следующий прототип:

void rewind(FILE *fp);

5. Функция fread() предназначена для чтения блоков данных из потока. Имеет прототип:

unsigned fread(void *ptr, unsigned size,

unsigned n, FILE *fp);

Она читает n элементов данных, длиной size байт каждый, из заданного входного потока fp в блок, на который указывает указатель ptr. Общее число прочитанных байтов равно произведению n*size. При успешном завершении функция fread() возвращает число прочитанных элементов данных, при ошибке - 0.

6. Функция fwrite() предназначена для записи в файл блоков данных. Имеет прототип:

unsigned fwrite(void *ptr, unsigned size,

unsigned n, FILE *fp);

Она добавляет n элементов данных, длиной size байт каждый, в заданный выходной файл fp. Данные записываются с позиции, на которую указывает указатель ptr. При успешном завершении операции функция fwrite() возвращает число записанных элементов данных, при ошибке - неверное число элементов данных.

2. Подход с использованием возможностей языка С++

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

Файловый поток для чтения открывается следующим образом:

ifstream идентификатор_потока(имя_файла,ключи_потока);

Например:

ifstream input("input.txt",ios::in);

- открывается файловый поток с идентификатором input для чтения из файла. Такой файловый поток должен быть по аналогии с Си и обязательно закрыт: input.close();

Файловый поток для записи открывается так:

ofstream идентификатор_потока(имя_файла,ключи_потока);

Например:

ofstream output("output.txt",ios::out);

Этот поток также должен быть закрыт:

output.close();

Как же работать с такими потоками? Очень просто:


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: