Для чтения и записи двоичных файлов в файловой системе языка С имеется две функции: fread() и fwrite(). Эти функции позволяют читать и записывать блоки данных любого типа. Их прототипы следующие:
size_t fread (void *буфер, size_t колич_байт, size_t счетчик, FILE *уф);
size_t fwrite (const void *буфер, size_t колич_байт, size_t счетчик, FILE *уф);
Для fread() буфер – это указатель на область памяти, в которую будут прочитаны данные из файла. А для fwrite() буфер – это указатель на данные, которые будут записаны в файл. Значение счетчик определяет, сколько считывается или записывается элементов данных, причем длина каждого элемента в байтах равна колич_байт. (Тип size_t определяется как одна из разновидностей целого типа без знака.) И, наконец, уф – это указатель файла, то есть на уже открытый поток.
Функция fread() возвращает количество прочитанных элементов. Если достигнут конец файла или произошла ошибка, то возвращаемое значение может быть меньше, чем счетчик. А функция fwrite() возвращает количество записанных элементов. Если ошибка не произошла, то возвращаемый результат будет равен значению счетчик.
|
|
Более просто список параметров этих функций можно представить следующим образом: указатель на область оперативной памяти, размер блока, количество блоков и файловая переменная.
В качестве иллюстрации работы с двоичным файлом приведём фрагменты программ для записи в файл и чтения из файла одномерного массива. Для краткости функции открытия fopen() и закрытия fclose() файла опущены.
Запись в файл:
1) поэлементная запись
const int Nmax = 10; // максимальная размерность массива
int Mas[Nmax];
int N; // реальная размерность массива
for (int i = 0; i < N; i++)
fwrite(Mas, sizeof(Mas[i]), N, fp);
Вместо Mas можно использовать &Mas[0], а вместо sizeof(Mas[i]) – sizeof(int).
2) блоковая запись – 1-й вариант. Здесь в качестве размера блока указан размер одного элемента массива sizeof(int), а в качестве количества блоков – количество элементов массива N.
fwrite(Mas, sizeof(int), N, fp);
3) блоковая запись – 2-й вариант. Здесь в качестве размера блока указан размер всего массива sizeof(int) * N, а количество блоков, соответственно, равно единице.
fwrite(Mas, sizeof(int) * N, 1, fp);
4) блоковая запись – 3-й вариант. Используется тогда, когда реальная размерность массива совпадает с максимальной.
fwrite(Mas, sizeof(Mas), 1, fp);
Пример чтения из файла представлен для случая, когда известен тип массива Mas (например, int), но не известно количество элементов. В примере использовано то обстоятельство, что функция fread() является типизированной и возвращает количество прочитанных блоков.
int Mas[Nmax];
int i, temp, N;
i = 0;
while (fread(&temp, sizeof(int), 1, fp)!= 0)
{
Mas[i] = temp;
i++;
}
N = i;
Поскольку размерность массива, записанного в файл, не известна, чтение продолжается до тех пор, пока не будет достигнут конец файла. До начала цикла номер элемента массива i принимает начальное значение. Затем очередной элемент массива считывается из файла в промежуточную переменную temp. Если чтение было успешным, то функция fread() возвращает 1 (т.е. количество прочитанных элементов). Тогда прочитанное значение копируется из переменной temp в соответствующий элемент массива Mas[i], после чего номер элемента i увеличивается на единицу. Если же был достигнут конец файла и очередной элемент прочесть не удалось, то функция fread() возвращает 0, и цикл чтения массива из файла завершается. При этом количество реально прочитанных элементов N будет равно текущему значению переменной i.
|
|