Поэлементный ввод и вывод

При вводе с клавиатуры и выводе на экран или в текстовый файл с каждым полем струк-

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

books.txt.

Book b;

FILE *fp;

printf("Автор ");

gets(b.author);

printf("Название книги ");

gets(b.title);

printf("Год издания, кол-во страниц ");

scanf("%d%d", &b.years, &b.pages);

fp = fopen("books.txt", "a"); // дописать в конец файла

fprintf(fp, "%s\n%s\n%d %d\n",

b.author, b.title, b.years, b.pages);

fclose (fp);

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

Структуры очень удобно записывать в двоичные файлы, поскольку можно за 1 раз прочи-

тать или записать сразу одну или даже несколько структур. Вспомним, что при чтении из дво-

ичного файла функции fread надо передать адрес нужной области памяти (куда записать про-

читанные данные), размер одного блока и количество таких блоков. Для того, чтобы не вычис-

лять размер структуры вручную (можно легко ошибиться), применяют оператор sizeof.

Book b;

int n;

FILE *fp;

fp = fopen("books.dat", "rb");

n = fread (&b, sizeof(Book), 1, fp);

if (n == 0) {

printf ("Ошибка при чтении из файла");

}

fclose (fp);

Можно было также вместо sizeof(Book) написать sizeof(b), поскольку запись b – это

как раз один экземпляр структуры Book. Функция fread возвращает число удачно прочитанных элементов (в нашем случае – структур). Поэтому если в примере переменная n равно нулю,чтение закончилось неудачно и надо вывести сообщение об ошибке.

Для записи структуры в двоичный файл используют функцию fwrite. Ее параметры – те

же, что и у fread. Пример ниже показывает добавление структуры в конец двоичного файла

books.dat.

Book b;

FILE *fp;

// здесь надо заполнить структуру

fp = fopen("books.dat ", "ab");

fwrite(&b, sizeof(Book), 1, fp);

fclose (fp);

Копирование

Пример. Пусть в памяти выделено две структуры одного типа и в одну из них записаны какие-то данные. Требуется скопировать все данные из первой структуры во вторую.

Пусть структуры имеют тип Book и называются b1 и b2. Существуют три способа решения этой задачи. Самый сложный – копирование каждого поля отдельно:

Book b1, b2;

// здесь заполняем структуру b1

strcpy (b2.author, b1.author);

strcpy (b2.title, b1.title);

b2.year = b1.year;

b2.pages = b1.pages;

Можно использовать специальную функцию memcpy, которая умеет копировать блоки памяти.Для ее использования надо подключить к программе заголовочный файл mem.h.

#include <mem.h>

Book b1, b2;

// здесь нужно заполнить структуру b1

memcpy(&b2, &b1, sizeof(Book)); // куда, откуда, сколько байт

Самый простой способ – третий. Достаточно просто написать

b2 = b1;

При этом программа скопирует одну структуру в другую «бит в бит». Зачем же рассказыватьпро остальные два способа? Только для того, чтобы понять, как это все работает, посколькунепонимание ведет к трудноуловимым ошибкам.

Массивы структур

Структуры служат для обработки большого объема информации, поэтому чаще всего в

программе используются массивы структур. Они объявляются так же, как обычно, но предварительно (выше) надо объявить саму структуру как новый тип данных.

Для обращения к полю структуры также используют точку, но теперь надо указать в квад-

ратных скобках еще номер нужной структуры, например

Book A[20];

...

A[12].pages = 50;

for (i = 0; i < 20; i ++) // цикл по всем структурам в массива

puts(A[i].title); // вывести название книги

Если вы работаете с двоичными файлами, то чтение и запись всего массива структур выполняется в одну строчку. Покажем приемы работы с двоичным файлом на примере.

Пример. В файле books.dat записаны структуры типа Book. Известно, что их не больше 100.

Требуется прочитать их в память, у всех книг установить 2009 год издания и записать обратнов тот же файл.

Поскольку по условию известно, что структур не больше 100, заранее выделяем в памяти массив на 100 структур.

Book b[100];

При чтении из файла пытаемся читать все 100 структур:

n = fread (&b[0], sizeof(Book), 100, fp);

Чтобы определить, сколько структур было в действительности прочитано, используем значение n, которое функция fread возвращает в качестве результата. Вот полная программа:

#include <stdio.h>

struct Book { // объявление нового типа данных

char author[40];

char title[80];

int year;

int pages;

};

Main()

{

Book b[100]; // выделение памяти под массив структур

int i, n;

FILE *fp;

fp = fopen("books.dat", "rb"); // читаем 100 структур

n = fread(&b[0], sizeof(Book), 100, fp); // прочитали n шт.

fclose (fp);

for (i = 0; i < n; i ++) // обрабатываем все, что прочитали

b[i].year = 2009;

fp = fopen("books.dat", "wb"); // записываем n шт.

fwrite (b, sizeof(Book), n, fp);

fclose (fp);

}


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



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