Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 22.07.2014, 23:28   #1
Faltfromoss
Новичок
Джуниор
 
Регистрация: 22.07.2014
Сообщений: 1
Вопрос Запись и чтение структуры в/из файла

Добрый день. Такая проблема.

Есть несколько участков кода.

Структура "Абонент":

Код:
struct Subscriber
{
   char FIO [50];
   int YearOfBirth;
   char Town [20];
   char Number [15];
 
   Subscriber * left, * right, * parent;
};
А также класс Tree - бинарное дерево, которое сортирует эти структуры.
В классе Tree есть функция SaveInFile - сохранение всех записей в файл:

Код:
void Tree::SaveInFile (Subscriber * Node, FILE * F)
{
    if(Node != 0)
    {
        SaveInFile (Node->left, F);
            fwrite (Node, sizeof (Subscriber), 1, F);
        SaveInFile (Node->right, F);
    }
}
И, соответственно функция чтения из файла:

Код:
void Tree::ReadOutFile (FILE * F)
{
    while (!feof (F))
    {
        Subscriber *Node = new Subscriber;
        fread (Node, sizeof (Subscriber), 1, F);
        Insert (Node); // вставляет указатель на считанную структуру в дерево
    }
}
Метод SaveInFile в свою очередь вызывается в функции SaveBase:

Код:
void  SaveBase (Tree &T)        //сохранение базы в файл
{
    int key = 0;
    // записать в существующий файл или создать новый?
    do
    {
        system ("cls");     
        cout<<endl<<"\tЗаписать в существующий файл (1) или создать новый (2) ?: ";
        key = _getch();
    } while (key !=49 && key!=50);
    
    FILE *Base;
    char buffer [200];
 
    switch (key)
    {
    case '1':                   //Если в существующий
        system ("cls");         
        cout<<endl<<"\tВведите путь или имя файла: ";
        gets_s (buffer);
        strcat (buffer, ".txt");
        if(_access(buffer, 00) == -1)
        {
            cout<<endl<<"\tУказан неверный путь или имя файла";
            return;
        }
        
        if (!(Base = fopen (buffer, "w")))
        {
            cout<<endl<<endl<<"\tОшибка при открытии файла"<<endl<<endl;
            return;
        }
        T.SaveInFile (T.GetRoot(), Base);
        fclose (Base);
        cout<<endl<<endl<<"\t\tФайл записан успешно!"<<endl;
        break;
    case '2':           //если новый файл
        system ("cls");         
        cout<<endl<<"\tВведите имя файла: ";
        gets_s (buffer);
        strcat (buffer, ".txt");
        if (!(Base = fopen (buffer, "w")))
        {
            cout<<endl<<endl<<"\tОшибка при открытии файла"<<endl;
            return;
        }
        T.SaveInFile (T.GetRoot(), Base);
        fclose (Base);
        cout<<endl<<endl<<"\t\tФайл записан успешно!"<<endl;
        break;
    }
}
Код:
void  ReadBase (Tree &T)        //чтение базы из файла
{
    FILE *Base;
    char buffer [200];
    if (T.GetRoot ())
        T.Del ();
    system ("cls");         
    cout<<endl<<"\tВведите путь или имя файла: ";
    gets_s (buffer);
    strcat (buffer, ".txt");
    if(_access(buffer, 00) == -1)
    {
        cout<<endl<<"\tУказан неверный путь или имя файла"<<endl;
        return;
    }
        
    if (!(Base = fopen (buffer, "r")))
    {
        cout<<endl<<endl<<"\tОшибка при открытии файла"<<endl<<endl;
        return;
    }
    
    T.ReadOutFile (Base);
    fclose (Base);
    cout<<endl<<endl<<"\t\tФайл считан успешно!"<<endl;
    
}
Проблема в том, что, когда я считываю последовательно записи из файла, нужно же закончить чтение, что обычно делается командой feof вот как здесь:

Код:
while (!feof (F))
    {
        Subscriber *Node = new Subscriber;
        fread (Node, sizeof (Subscriber), 1, F);
        Insert (Node);
    }
Но, дело в том, что данные в файл записываются абсолютно все, то есть вместе с неиспользованными байтами из символьных массивов FIO, Town, Number. И в итоге после чтения всей нужной инфы, он вконце дописывает весь остальной мусор из файла. Ну вот пример.

1) Ввожу инфу:

111.PNG

2) Вывожу на экран:

222.jpg

3) Сохраняю в файл:

333.PNG

4) Считываю из файла:

4444.PNG

5) Вывожу считанную информацию на экран:

555.jpg

В общем я понимаю причину, но не могу сообразить, как сделать, чтобы считывалось всё, без мусора. Записывать и считывать построчно путём fputs() и fgets() как то глупо и накладно как по мне :/ Может я как-то неверно описал функции записи и чтения?

На cyberforum.ru внятного ответа пока не дали и сам до сих пор не могу сообразить :/
Faltfromoss вне форума Ответить с цитированием
Старый 23.07.2014, 08:39   #2
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,331
По умолчанию

Попробуйте вывести информацию ДО сохранения в файл - возможно "мусор" уже изначально в данных.
waleri вне форума Ответить с цитированием
Старый 23.07.2014, 23:01   #3
Zenon
Пользователь
 
Регистрация: 03.07.2014
Сообщений: 32
По умолчанию

Вот здесь может быть проблема:

Код:
while (!feof (F))
    {
        Subscriber *Node = new Subscriber;
        fread (Node, sizeof (Subscriber), 1, F);
        Insert (Node);
    }
Представьте себе, что только что считана последняя запись. Указатель стоит на конце файла, но попытки чтения из файла за концом файла еще не было. Соответственно условие while (!feof (F)) пропускает вас внутрь цикла. Далее вы создаете Node (неинициализированную, т.е. с мусором) далее fread пытается читать за концом файла - с ошибкой, но вы ее не проверяете, и Node не меняется, остается с мусором, и следующий оператор сует мусорную Node в дерево. Потом while (!feof (F)) обнаруживает конец файла, и цикл заканчивается с одной лишней мусорной нодой.
Zenon вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Чтение и запись структуры в бинарный файл. jack291 Помощь студентам 2 20.08.2011 18:07
Чтение/запись структуры Кипящий чайник Общие вопросы C/C++ 10 19.01.2011 21:15
Чтение и запись структуры в бинарный файл Bed Alice Общие вопросы C/C++ 1 09.11.2010 21:17
Запись структуры и чтение из файла [MI_nor] Общие вопросы C/C++ 6 08.04.2009 15:52