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

В этом пункте при работе с двоичными файлами используются структуры.

Пример 1. Работа с файлом структур, каждая из которых содержит информацию о компьютере.

/* Объявляем глобально тип структуры (tComp), переменную этого типа (pibm) и указатель файла (lf), которые будут использоваться в нескольких функциях. */

struct tComp {

char model[15]; // Модель (или название) компьютера.

int mem; // Объём памяти компьютера.

} pibm;

FILE *lf;

// Создание файла содержит следующие этапы:

void MyCreate()

{ clrscr(); int k=0, flag;

// 1. Открытие файла

lf=fopen("d:\\ana\\cpp\\C++Lections2semestr\\files\\f1.dat","wb");

if (lf==NULL) { printf("Error\n"); return;

}

else printf("File is opened for creating\n");

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

do {

/* 2. В цикле подготовка одной записи, то есть полей структуры. Здесь ввод с экрана. Кроме этого, в других задачах некоторые поля могут вычисляться, вводиться из другого файла и т.д */

printf("model ->");

scanf ("%s", pibm.model); // Ввод модели компьютера.

/* 3. Программируем условие выхода из цикла. Например, если в наименовании модели введём три и более подряд идущих символа ‘0’, то заканчиваем создание файла. Желательно, чтобы ввод поля, с помощью которого осуществляется проверка выхода из цикла, выполнялся как можно раньше, то есть в начале тела цикла. В противном случае придётся “вхолостую” вводить значения многих полей, которые не будут записаны в файл. */

if (strstr(pibm.model, "000")) break;

printf("Number ->");

scanf("%d", &pibm.mem); // Ввод параметра компьютера

/* 4. Записываем одну структуру, т. е. название одного компьютера и его числовой параметр из оперативной памяти (pibm) в файл (lf) */

fwrite(&pibm,sizeof(pibm),1,lf);

k++; // Счётчик всех записей

} while (1);

// 5. Закрытие файла.

fclose(lf);

/* 6. Используем полученные в процессе создания файла параметры. Здесь вывод количества всех записей. */

printf("\n Writed %3d records\n", k);

}

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

size_t fwrite(const void *buf, size_t size, size_t count, FILE *stream )

Здесь buf — указатель на область оперативной памяти, из которой информация записывается в файл. В нашем примере это указатель на структуру. Тип void здесь означает, что если файл открыт как двоичный, то в зависимости от конкретной задачи можно использовать указатель на данные других типов. Например, в следующем пункте будем использовать указатель на массив. Допускается и указатель на переменную простого типа. Для текстового файла это указатель на массив символов. Функция за один вызов записывает count элементов (порций информации) длиной size байт каждый из области оперативной памяти, определяемой с помощью buf, в файл, связанный с потоком stream. В нашем примере записывается одна структура. Указатель позиции в файле продвигается вперёд на количество записанных байт (символов).

Функция возвращает количество действительно записанных блоков (в смыле порций информации) по size байт каждый, которое в случае успешной записи равно указанному при вызове количеству count. Если это количество меньше, чем указано при вызове, то это означает, что произощла ошибка. Например, недостаточно места при записи блока.

Здесь, как и в строковых функциях, size_t — это беззнаковый целый тип. */

/* Чтение и анализ файла. Используя созданный в предыдущей функции файл, найдём количество компьютеров, память которых больше заданной. Для чтения файла необходимо предусмотреть следующие этапы: */

void MyRead()

{ int nRec=0, // Номер записи

kComp=0, // Количество компьютеров с заданным условием.

mem0; // Для критерия выбора записей

clrscr();

/* Ввод значения переменной mem0, которая будет использоваться в критерии анализа прочитанных записей. */

cout<<”mem0=”; cin>> mem0;

// 1.Открытие файла

lf=fopen("d:\\ana\\сpp\\C++Lections2semestr\\files\\f1.dat","rb");

if (lf==NULL)

{ printf("Error\n"); return;

}

else printf("File is opened for reading\n");

// 2. Чтение первой записи (одной структуры) вне цикла

fread (&pibm, sizeof(pibm),1,lf);

/* 3. В цикле записываем условие выхода из него. Чтение и анализ записей (структур) будем продолжать, пока не будет достигнут конец файла. */

while (!feof(lf))

{

//Получение и вывод на экран номера записи.

nRec++; printf("\n Record %d \n",nRec);

// 4. Используем прочитанную запись: выводим её на экран…

printf("Model %s\n", pibm.model);

printf("Memory %d\n", pibm.mem);

// … ианализируем её

if (pibm.mem > mem0) kComp++;

// 5. Читаем очередную запись в цикле

fread (&pibm, sizeof(pibm),1,lf);

}

// 6. Закрытие файла.

fclose(lf);

/* 7. Используем полученные при чтении и анализе файла результаты (k и kComp). */

printf ("\n Read %d records\n There are %d records: memory > %d ",

nRec, kComp, mem0);

}

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

size_t fread(void *buf, size_t size, size_t count, FILE *stream).

Здесь buf — указатель на область оперативной памяти, в которую будет помещена информация после чтения из файла. В нашем примере это указатель на структуру. Тип void здесь означает, что если файл открыт как двоичный, то в зависимости от конкретной задачи можно использовать указатель на данные других типов. Например, в следующем пункте будем использовать указатель на массив. Допускается и указатель на переменную простого типа. Для текстового файла это указатель на массив символов. Функция за один вызов читает count элементов (порций информации) длиной size байт каждый из файла, связанного с потоком stream, в область оперативной памяти, определяемой с помощью buf. В нашем примере читается одна структура. Указатель позиции в файле продвигается вперёд на size*count, т. е. количество прочитанных байт (символов).

Функция возвращает количество действительно прочитанных блоков (порций информации), которое в случае успешной записи равно указанному при вызове количеству count. Если это количество реально прочитанных объектов меньше, чем указано при вызове, то это означает, что произощла ошибка чтения или достигнут конец файла.

Здесь, как и в строковых функциях, size_t — это беззнаковый целый тип.

Функция добавления в конец файла почти ничем не отличается от функции создания файла. Предлагается её написать самостоятельно. Не забудьте при открытии файла вместо режима “ wb ” указать “ ab ”.*/

/* Описание головной программы смотри в 2.1. */

int main()

{ int flag=1;

while (flag)

{ cout << "\n1 -- CREATE"<<endl<<

"2 -- READ"<<endl<<

"0 -- EXIT"<<endl;

cin>>flag;

switch (flag)

{ case 1: MyCreate(); break;

case 2: MyRead(); break;

case 0: return 0;

}

}

}


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



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