Создание файла из 10 структур, используя функции и режим меню (Структура имеет вид: фамилия, номер телефона, дата рождения)

Страницы работы

4 страницы (Word-файл)

Содержание работы

Лабораторная работа №4

Вариант 6.

Задание 1. Используя функции и режим меню, создать файл из 10 структур, просмотреть файл, добавить в файл новую информацию и, применяя режим прямого доступа, выполнить задание по своему варианту. Структура имеет вид: фамилия, номер телефона, дата рождения. Внести в начало списка информацию о четырех новых знакомых.

Программа с пояснениями:

// Lab5.cpp : Defines the entry point for the console application.

//

#include "stdafx.h"

#include <stdio.h>

#include <conio.h>

#include <string.h>

#include <stdlib.h>

struct Kontakt{                      //Искомая структура (Имя, телефон, дата рождения)

            char FIO[10];

            char Tel[17];

            char Date[10];};

struct Kontakt t;

void input();                           //Процедура ввода новой таблицы

void print();                            //Процедура вывода таблицы на экран

void app();      //Процедура добавления записи в начало таблицы с помощью Temp файла

void add();      //Процедура добавления записи в начало таблицы произвольным доступом

FILE *f;

int main(int argc, char* argv[])

{

            char c;

            while (1){

                        system("cls");             //В Visual C нет clrscr

                        puts("1. New");          //Выводим менюшку на экран

                        puts("2. View");

                        puts("3. Add");

                        puts("4. Add ver 2.");

                        puts("0. Exit");

                        c=getch();

                        switch(c){                   //Что будем делать:

                                    case '1':input();break; //Вводим таблицу заново

                                    case '2':print();break; //Печатаем

                                    case '3':app();break;   //Добавляем запись

                                    case '4':add();break;   //Добавляем запись

                                    case '0':return 0;

                                    default : puts(" Wrong key");

                        }

            }

            return 0;

}

void input()

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

//приведена в лекциях.

{

            char ch;

            f=fopen("Data.dat","wb");     //Режим записи, пишем с начала файла и дальше

            do{

                        system("cls");

                        printf("\n Input new kontakt\n");      //Получаем структуру с клавиатуры

                        printf("\n FIO: "); scanf("%s",t.FIO);

                        printf(" Tel: "); scanf("%s",t.Tel);

                        printf(" Birthdate: "); scanf("%s",t.Date);

                        fwrite(&t,sizeof(t),1,f);                      //Пишем в файл

                        printf("\n Exit? y/n ");

                        ch=getch();

            }

            while (ch != 'y');

            fclose(f);

}

void print()

//Вывод данных из файла на экран. Функция идентична фнкции, предложенной в лекциях

{

            int i;

            system("cls");

            f=fopen("Data.dat","rb");      //Режим побайтового чтения

            i=1;

            fread(&t,sizeof(t),1,f);          

            while (!feof(f)){                     //Выводим на экран

                        printf("\n %3d FIO %10s Tel %17s Birthdate %10s", i, t.FIO, t.Tel, t.Date);

                        fread(&t,sizeof(t),1,f);           //Читаем из файла

                        i++;

            }

getch();

}

void app()

/*Начинается самое интересное! Функция добавления записи в начало файла, с использованием временного файла (последовательный доступ)*/

{         

            FILE *Temp;  //Временный файл

            Temp=fopen("Temp.dat","wb+");    //Временный файл в режиме записи

            char ch;

            f=fopen("Data.dat","rb");                  //Основной файл в режиме чтения

            int i=1;

            while (!feof(f))                                   //Пока основной файл не кончится

                        fputc(fgetc(f), Temp);                       //перекладываем содержимое в Temp.

            fclose(Temp);

            fclose(f);

            Temp=fopen("Temp.dat","rb");        //Временный файл в режиме чтения

            f=fopen("Data.dat","wb");                //Основной файл в режиме записи

            rewind(f);                               //На всякий случай

            rewind(Temp);

            do{

                        system("cls");

                        printf("\n Input new kontakt\n");      //Читаем структуру с экрана

                        printf("\n FIO: "); scanf("%s",t.FIO);

                        printf(" Tel: "); scanf("%s",t.Tel);

                        printf(" Birthdate: "); scanf("%s",t.Date);

                        fwrite(&t,sizeof(t),1,f);                      //Записываем в основной файл

                        while(!feof(Temp))

                             fputc(fgetc(Temp), f);                  //Перекладываем все содержимое

                        printf(" Exit? y/n ");                          //временного файла в основной

                        ch=getch();

            }

            while (ch != 'y');

            fclose(f);

            fclose(Temp);

/* Алгоритм очень простой, наглядный. По идее, временный файл после завершения функции нужно удалить, но это мелочи (пока не умею этого делать). Функция работает «на ура», видит конец файла, в общем с режимами последовательного доступа все понятно, проблем не возникало. */

}

void add()

/*Функция добавления записи в начало файла в режиме произвольного доступа. Вот здесь у меня возникли некоторые проблемы. Причем, объективных причин для этого, на мой взгляд, нет. В современной литературе, как правило, отсутствует информация по работе с бинарными файлами, и некоторая схожесть функций с методами класса CFile проблемы не решают. Основная проблема – неясно как ведет себя курсор текущей позиции в файле, при операциях чтения и записи. Дальше по порядку */

{         

            long i; //Смещение

            int kolvo;

            char ch;

            f=fopen("Data.dat","rb+");    //Режим произвольного доступа

            kolvo=0;         //Считаем количество записей в файле

            while (!feof(f)){

                        fread(&t,sizeof(t),1,f);           //После чтения записи увеличиваем содержимое

                        kolvo++;                                //переменной kolvo на единицу

            }

            /*Вот первая странность: kolvo всегда на единицу больше, чем реальное количество записей в файле. Причем последняя запись читается дважды. В чем проблема непонятно! По этой причине не работает следующий алгоритм:

            do{

                        fread(&t,sizeof(t),1,f); //читаем первую запись в структуру t

while (!feof(f)){

                                    fread(&t1,sizeof(t1),1,f); //читаем текущую запись в t1(еще структура

//типа Kontakt)

i=sizeof(t1);

fseek(f, -i, 1); //назад  на sizeof(t1) байт

                                    fwrite(&t,sizeof(t),1,f); //записываем предыдущую запись поверх

//текущей

                                    t=t1;  //t1 в t и

                                    getch();// следующая запись

                        }

По идее здесь должно происходить смещение всех записей на одну позицию вниз. После можно было бы переписать первую  запись на новую, и на этом работа закончена, но… Если в файле всего одна запись, то цикл while (!feof(f)) не должен запускаться, поскольку перед ним операцией чтения текущая позиция в файле должна быть установлена на конец файла, но он все равно запускается и зацикливается. Причем зацикливание происходит в любом случае, при любом количестве записей в файле. Даже если заменить fwrite на fread, то цикл будет бесконечное число раз читать последнюю запись. Поэтому так не делаем, делаем так: */

            printf(" kolvo=%d ",kolvo);

            for (i=(kolvo-2)*sizeof(t);i>=0;i-=sizeof(t)){          /*перебираем записи в файле, начиная с последней */

                        fseek(f, i, 0);   //позицию курсора на текущую запись

                        fread(&t,sizeof(t),1,f);           //читаем текущую запись

                        fseek(f, i+sizeof(t), 0);           /*позицию курсора на следующую за текущей!! Иначе работать не будет!! */

                        fwrite(&t,sizeof(t),1,f);          //Пишем

            }

                        system("cls");

                        printf("\n Input new kontakt\n");      //Читаем новую структуру

                        printf("\n FIO: "); scanf("%s",t.FIO);

                        printf(" Tel: "); scanf("%s",t.Tel);

                        printf(" Birthdate: "); scanf("%s",t.Date);

                        fseek(f, 0, 0);                          //Позицию курсора на начало файла

                        fwrite(&t,sizeof(t),1,f);          //Пишем

                        printf(" Exit? y/n ");

                        ch=getch();

            while (ch != 'y');

            fclose(f);

}          //Ура!!! Все работает, но  остался неприятный осадок…

Похожие материалы

Информация о работе