Математические задачи с использованием файлов

Во многих пособиях при рассмотрении fwite и fread ограничиваются задачами, в которых эти функции используются только для работы со структурой. Но ничто не мешает их применять, например, в матричных, геометрических и других математических задачах, в которых информацию необходимо хранить на внешнем устройстве.

Здесь будет рассмотрена р абота с файлом, содержащим “матрицу”, т. е. несколько одномерных массивов фиксированной одинаковой размерности. Количество таких массивов вводим в виде переменной n, а не константы.

Важным требованием к таким задачам является следующее. В оперативной памяти будем хранить только одну строку “матрицы” в виде статического одномерного массива, как показано в примере. Одномерный массив может быть и динамическим. Вся “матрица” в оперативной памяти храниться не будет, поэтому ни статически, ни динамически память для неё не резервируется. Заметим, что не любой матричный алгоритм можно так запрограммировать. Как правило, такой метод программирования можно использовать при обработке матрицы по строкам.

Кроме работы с файлами здесь показано, что задачу можно разбить на независимо разрабатываемые проекты (программы). Один из них создаёт файл, другой читает его, третий анализирует и так далее. Связь между ними осуществляется за счёт того, что в функции fopen() в разных программах записываем один и тот же физический файл. Каждая из таких программ может быть оформлена не функцией одного проекта, как это было в предыдущих пунктах, а в виде отдельного проекта, то есть для простоты, например, в виде одной основной функции main.

Создание файла одномерных массивом. Другими словами, “матрицу”, то есть несколько одномерных массивов записываем на внешнее устройство в файл.

// Определяем количество элементов в каждой строке матрицы.

#define m 5

main()

{

// В оперативной памяти будем хранить одну строку ”матрицы” размерности m.

int a[m];

FILE *arf;

arf= fopen("d:\\ANA\\cpp\\C++Lections2Semestr\\files\\farr.dat","wb");

// Объявляем переменную для количества строк “матрицы” и определяем её

int n; printf("\n");

cout<<"n="; cin>>n;

/* Внешний цикл для записи в файл n одномерных массивов, каждый из которых размерности m, то есть n строк матрицы. */

for (int i=0; i<n;i++)

{ cout<<endl;

/* Формируем одномерный массив по некоторому правилу. Здесь возможны следующие варианты подготовки одномерного массива:

ввод массива с экрана или из заранее созданного текстового или двоичного файла;

получение элементов массива с помощью датчика случайных чисел;

формирование массива по некоторому алгоритму

и другие варианты. */

for (int j=0;j<m;j++)

{ a[j]=(i+1)*(j+1);

/* Вывод на экран для дальнейшей проверки, правильно ли запишем в файл и прочитаем из него. */

printf("%5d",a[j]);

}

/* Записываем одномерный массив (строку “матрицы”) в файл одним из указанных способов */

fwrite (a, sizeof(a),1, arf);

//fwrite(&a[0],m*sizeof(int),1,arf);

//fwrite(a,m*4,1,arf);

}

fclose(arf); cout<<"\nFile was created";

getch(); return 0;

}

Описание функции fwrite смотри в 3.1.

Независимо от варианта использования функции fwrite() она выполняется столько раз, сколько одномерных массивов мы записываем. За один вызов функция записывает в файл, связанный с потоком arf, одну порцию информации из m целых чисел. Размер этого блока sizeof(a), или m*sizeof(int), или m*4 байт. Записываемые в файл данные выбираются из области оперативной памяти, начиная с адреса a, или &a[0], то есть с начала расположения одномерного массива.

Добавление в конец файла одномерных массивов фиксированной размерности (строк “матрицы”) аналогично созданию файла. Только при открытии файла вместо режима “ wb ” необходимо указать “ ab ”. Кроме этого, в предложенном варианте элементы массива формируются случайным образом. Количество добавляемых одномерных массивов (строк “матрицы “) не определяется. Массивы добавляем, пока не введём символ ‘*’. При этом введённые символы (‘*’) в файл не записываются.

#define m 5

main()

{ int a[m],i; char ch; FILE *arf;

randomize();

arf= fopen("d:\\ANA\\cpp\\C++Lections2Semestr\\files\\farr.dat","ab");

do { cout<<endl;

for (i=0;i<m;i++)

{a[i]=random(100)-50;

cout<<a[i]<<" ";

}

fwrite(a,sizeof a,1,arf);

cout<<"\n * -- exit";

ch=getch();

} while (ch!='*');

fclose(arf);

return 0;

}

Чтение файла одномерных массивов. Читаем из файла записанные в предыдущих программах одномерные массивы размерности m. Другими словами, читаем “матрицу” с фиксированным (одинаковым) количеством элементов в каждой строке и произвольным количеством строк.

Так как мы могли добавлять одномерные массивы, то их количество, т. е. количество строк “матрицы”, не обязательно должно совпадать с тем, которое было при создании файла. Поэтому цикл для чтения всех массивов организован с помощью функции feof().

#define m 5

main()

{

/*Как и при создании файла, в оперативной памяти будем хранить одну строку ”матрицы”, то есть один одномерный массив фиксированной размерности m. */

int a[m];

FILE *arf;

arf= fopen("d:\\ANA\\cpp\\C++Lections2Semestr\\files\\farr.dat","rb");

clrscr();

/* Вне цикла читаем первый одномерный массив (первую строку “матрицы”) из файла в оперативную память. */

//fread(a, m*sizeof(int), 1, arf); или

// fread(a, m*4, 1, arf); или

fread(a, sizeof(a), 1, arf);

while (!feof(arf))

/* Цикл будет выполняться, пока не достигнем конца файла. Использование цикла for (int i=0; i<n; i++) неправильно, так как кроме создания файла предусмотрено добавление одномерных массивов. Поэтому их количество могло измениться и мы, вообще говоря, не знаем его.*/

{

/* Использование прочитанного одномерного массива. В этом примере ограничились его выводом. Реально на этом этапе возникает необходимость в алгоритмизации и программировании задач по теме “одномерные массивы”*/

printf("\n");

for (int j=0; j<m; j++)

printf("%5d",a[j]);

/* Читаем следующий одномерный массив (строку “матрицы”) из файла в оперативную память. Как и вне цикла, возможны разные варианты использования функции fread */

fread(a, sizeof(a),1,arf);

}

fclose(arf); getch(); return 0;

}

Описание функции fread смотри в 3.1.

Независимо от варианта использования функции fread() она выполняется столько раз, сколько одномерных массивов есть в файле. За один вызов функция читает из файла, связанного с потоком arf, одну порцию информации из m целых чисел, т. е. sizeof(a) ( или m*sizeof(int), или m*4 байт). Эти прочитанные данные записываются в область оперативной памяти, начиная с адреса a (или &a[0]).


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



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