Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Язык Си. Лабораторные работы / Справочник. Часть 2 (СПбГУТ).doc
Скачиваний:
54
Добавлен:
10.09.2019
Размер:
802 Кб
Скачать
☆

2.12.2. Работа с двоичными файлами

2.12.2.1. Вычисление суммы чисел, содержащихся в двоичном файле.

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

Решение. Интерфейс функции. Имя функции sum_dbl_num_in_bin_file. Функция должна иметь один параметр – файловый указатель. Возвращаемое значение – вычисленная сумма. Прототип функции будет иметь вид:

double sum_dbl_num_in_bin_file(FILE* in_file);

Реализация функции. Удобно выбрать для чтения данных из файла функцию fread(), обеспечивающую чтение очередного блока чисел. Структура алгоритма − вложенные циклы. До входа во внешний цикл необходимо определить и инициализировать переменную sum, которая будет использоваться для вычисления искомой суммы. Внешний цикл должен обеспечивать чтение очередного блока чисел, а внутренний цикл − суммировать числа этого блока. В связи с тем, что размеры запрошенного и прочитанного блока могут не совпадать, следует контролировать число блоков, которое возвращает функция fread().Для этой цели в программе служит переменная n. Программный код разработанной функции приведен ниже.

#include<stdio.h> #define MSIZE 256 double sum_dbl_num_in_bin_file(FILE* in_file) { double sum = 0; double ar[MSIZE]; while(!feof(in_file)) { int n = fread(ar, sizeof(double), MSIZE, in_file); for(int i = 0; i < n; i++)

sum += ar[i]; } return sum; }

2.12.2.2. Чтение числа из заданной позиции двоичного файла

Постановка задачи. Имеется числовой двоичный файл, содержащий числа типа double. Прочитать число, находящееся в позиции num.

Решение. Интерфейс функции. Имя функции read_number_from_bin_file. Функция должна иметь два параметра: файловый указатель in и целочисленный параметр num. Возвращаемое значение – прочитанное число. Прототип функции будет иметь вид:

double read_number_from_bin_file(FILE* in, int num);

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

double read_number_from_bin_file(FILE* in, int num) { //Вычислим начальную позицию n-го числа long pos =(long)(num – 1) * sizeof(double); //Переместимся к началу n-го числа fseek(in, pos, SEEK_SET); //Читаем n-ое число double value;

fread(&value, sizeof(double), 1, in); return value;

}

2.12.2.3.Замена всех отрицательных чисел двоичного файла нулями

Постановка задачи. Имеется числовой двоичный файл, содержащий числа типа double. Заменить все вхождения отрицательных чисел нулями. Решение задачи оформить в виде функции.

Интерфейс функции. Выберем для функции «говорящее» имя – replace_neg_num_with_zeros. Функция будет предназначена для модификации файла. Такая функция может не иметь возвращаемого значения. Функция должна иметь один формальный параметр − файловый указатель, в качестве имени которого выберем идентификатор in_out. В заключение разработки интерфейса приведем заголовок разрабатываемой функции:

void replace_neg_num_with_zeros(FILE* in_out)

Реализация функции. Особенностью данной функции является работа в режиме модификации (режим чтения-записи). Заметим, что при открытии файла в таком режиме в функции fopen() следует указывать во втором ее параметре знак + (b+). В этом случае поток можно использовать как для ввода, так и для вывода. Однако операции ввода и вывода не могут следовать непосредственно друг за другом. Они должны быть отделены вызовом одной из следующих функций: fsetpos(), fseek(), rewind или fflush() [7, стр. 377]. В реализации, приведенной ниже, для этой цели используется функция fseek(). В теле функции следует организовать итерационный цикл. Требуемые действия отражены в комментариях.

void replace_neg_num_with_zeros(FILE* in_out) { int n;//n – оличество прочитанных чисел double x; double zero = 0;//Для замены отрицательного числа нулем while(!feof(in_out)) { // Читаем очередное число n = fread(&x, sizeof(double), 1, in_out); if(0 == n) //Достигнут конец файла continue;//Передаем управление инструкции while if(x < 0)//Требуется ли замена очередного числа? { //Замена нужна. Вернемся к месту замены fseek(in_out, -(long)sizeof(double), SEEK_CUR); //Выполним замену fwrite(&zero, sizeof(double), 1, in_out); //Подготовимся к смене режима записи на режим чтения fseek(in_out, 0L, SEEK_CUR); } } }