Форум программистов, компьютерный форум CyberForum.ru

Запись и чтение структуры в/из файла - C++

Восстановить пароль Регистрация
 
Faltfromoss
0 / 0 / 0
Регистрация: 28.03.2014
Сообщений: 31
21.07.2014, 23:46     Запись и чтение структуры в/из файла #1
Столкнулся с очередной проблемой. Есть несколько участков кода:

Структура "Абонент":
C++
1
2
3
4
5
6
7
8
9
struct Subscriber
{
   char FIO [50];
   int YearOfBirth;
   char Town [20];
   char Number [15];
 
   Subscriber * left, * right, * parent;
};
А также класс Tree - бинарное дерево, которое сортирует эти структуры.
В классе Tree есть функция SaveInFile - сохранение всех записей в файл:

C++
1
2
3
4
5
6
7
8
9
void Tree::SaveInFile (Subscriber * Node, FILE * F)
{
    if(Node != 0)
    {
        SaveInFile (Node->left, F);
            fwrite (Node, sizeof (Subscriber), 1, F);
        SaveInFile (Node->right, F);
    }
}
И, соответственно функция чтения из файла:
C++
1
2
3
4
5
6
7
8
9
void Tree::ReadOutFile (FILE * F)
{
    while (!feof (F))
    {
        Subscriber *Node = new Subscriber;
        fread (Node, sizeof (Subscriber), 1, F);
        Insert (Node); // вставляет указатель на считанную структуру в дерево
    }
}
Метод SaveInFile в свою очередь вызывается в функции SaveBase:

Кликните здесь для просмотра всего текста

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
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;
    }
}


И соответствующая функция ReadBase:
Кликните здесь для просмотра всего текста

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
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 вот как здесь:

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

Запись и чтение структуры в/из файла

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

Запись и чтение структуры в/из файла

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

Запись и чтение структуры в/из файла

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

Запись и чтение структуры в/из файла

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

Запись и чтение структуры в/из файла

В общем я понимаю причину, но не могу сообразить, как сделать, чтобы считывалось всё, без мусора. Записывать и считывать построчно путём fputs() и fgets() как то глупо и накладно как по мне :/ Может я как-то неверно описал функции записи и чтения?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
21.07.2014, 23:46     Запись и чтение структуры в/из файла
Посмотрите здесь:

Чтение структуры из файла и запись нового C++
Запись\чтение структуры в\из файл(а) C++
Ansi c, запись и чтение структуры из файла. Накосячил от души C++
C++ Запись/чтение вектора в/из файла.Структуры
C++ Запись и чтение структуры с файла
C++ Запись структуры и её чтение из файла
Запись структуры и чтение из файла в структуру ( как бы лучше ) C++
Чтение/запись структуры C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Vourhey
Почетный модератор
6468 / 2243 / 123
Регистрация: 29.07.2006
Сообщений: 12,635
21.07.2014, 23:53     Запись и чтение структуры в/из файла #2
Инициализируй память структуры, например, нулями. Тогда считанные строки должны выглядеть нормально.
Я бы, честно, говоря использовал какой-нибудь формат, например, XML.
Faltfromoss
0 / 0 / 0
Регистрация: 28.03.2014
Сообщений: 31
22.07.2014, 21:53  [ТС]     Запись и чтение структуры в/из файла #3
Цитата Сообщение от Vourhey Посмотреть сообщение
Инициализируй память структуры, например, нулями. Тогда считанные строки должны выглядеть нормально.
Я бы, честно, говоря использовал какой-нибудь формат, например, XML.
Что-то вроде такого?

C++
1
2
3
4
5
6
7
8
9
10
struct Subscriber
{
   char FIO [50];
   int YearOfBirth;
   char Town [20];
   char Number [15];
 
   Subscriber * left, * right, * parent;
   Subscriber (): left (0), right (0), parent (0) {}
};
Попробовал, не получается. Об XML пока не знаю ничего :/
Yandex
Объявления
22.07.2014, 21:53     Запись и чтение структуры в/из файла
Ответ Создать тему
Опции темы

Текущее время: 18:10. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru