Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.91/11: Рейтинг темы: голосов - 11, средняя оценка - 4.91
0 / 0 / 0
Регистрация: 09.06.2013
Сообщений: 9

Некорректно работает сохранение или открытие файла

06.06.2019, 11:58. Показов 2370. Ответов 11

Студворк — интернет-сервис помощи студентам
День добрый!
Сохраняю вектор в файл, а потом загружаю содержание файла в вектор, строк в открытом векторе получается в 32 раза больше, выводятся сначала строки которые были в векторе а потом это количество строк увеличенное в 32 раза заполняется кракозябрами или пустотой.


Unit1.h
C++
1
2
3
4
5
6
7
8
9
struct LonelyPeople{
    char name[30];
    char sex[10] ;
    int age;
    char education[50];
    int height ;
}
 
extern vector <LonelyPeople> ManyPeople;
Unit1.cpp
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
vector <LonelyPeople> ManyPeople;
 
void __fastcall TForm1::N2Click(TObject *Sender)
{
    SaveDialog1->Execute();
    FILE *f = fopen(AnsiString(SaveDialog1->FileName).c_str(), "w+b");
 
    if( f )
    {
        for (int i = 0; i < ManyPeople.size(); i++) {
            fwrite(&ManyPeople[i], sizeof(LonelyPeople), sizeof(ManyPeople), f);
        }
 
    }
    else
    {
        ShowMessage("file error");
    }
 
    fclose( f );
}
 
void __fastcall TForm1::N3Click(TObject *Sender)
{
    ManyPeople.clear(); // очистить массив при загрузке
 
    OpenDialog1->Execute();
    FILE *f = fopen(AnsiString(OpenDialog1->FileName).c_str(), "r+b");
 
    if( f==0 )
    {
        ShowMessage("file error");return;
    }
 
    for(int i=0;i<ManyPeople.max_size();i++)
    {
        LonelyPeople s;
        fread(&s,sizeof(LonelyPeople),1,f);
        if(feof(f)) break;
        ManyPeople.push_back(s);
    }
 
    fclose(f);
}
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
06.06.2019, 11:58
Ответы с готовыми решениями:

Открытие и сохранение файла
Привет всем, подскажыте как открыть файл в С++ без Опен диалога и как збереч его, при етом с файла нужно считать инфу. (Файл в форматие...

некорректно работает цикл или условие
У меня такая проблема. По заданию я написал код , где я набираю в вектор значения , строку , далее число. Сохраняю всё это дело в...

Сохранение вектора в файл работает, а с загрузкой из файла беда
сохранение в файл, работает успешно fstream fdat; fdat.open(&quot;book.dat&quot;, ios::out | ios::trunc); if (!fdat) { ...

11
Модератор
Эксперт С++
 Аватар для zss
13773 / 10966 / 6491
Регистрация: 18.12.2011
Сообщений: 29,246
06.06.2019, 12:30
Цитата Сообщение от Fortuno Посмотреть сообщение
fwrite(&ManyPeople[i], sizeof(LonelyPeople), sizeof(ManyPeople), f);
Таким способом контейнеры записывать нельзя.
Т.к. данные находятся в динамической памяти, а не внутри структуры.
Придется писать поэлементно.
C++
1
2
for(auto p:ManyPeople)
  fwrite(&p,sizeof(p),1,f);
или
C++
1
2
for(auto p=ManyPeople.begin();p!=ManyPeople.end();++p)
  fwrite(p,sizeof(*p),1,f);
0
 Аватар для eva2326
1673 / 501 / 107
Регистрация: 17.05.2015
Сообщений: 1,519
06.06.2019, 12:31
Цитата Сообщение от Fortuno Посмотреть сообщение
строк в открытом векторе получается в 32 раза больше, выводятся сначала строки которые были в векторе а потом это количество строк увеличенное в 32 раза заполняется кракозябрами или пустотой.
Запись:
C++
1
for (int i = 0; i < ManyPeople.size(); i++)
Чтение:
C++
1
for(int i=0;i<ManyPeople.max_size();i++)
Обратили внимание на счетчики циклов?


Количество сохраняемых элементов: ManyPeople.size()
Количество загружаемых элементов: ManyPeople.max_size()

Загружать нужно столько же, сколько было сохраненно.
А не максимально-возможное.

По хорошему, вначале вы сохраняете количество записей.
И только после этого сохраняете сами записи.

При загрузке: сначала загружаете количество записей.
А затем, зная этого количество, прогружаете сами записи.
1
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,818
06.06.2019, 12:33
Лучший ответ Сообщение было отмечено Fortuno как решение

Решение

Цитата Сообщение от Fortuno Посмотреть сообщение
fwrite(&ManyPeople[i], sizeof(LonelyPeople), sizeof(ManyPeople), f);
Скорее всего дело в этом:
C++
1
fwrite(&ManyPeople[i], sizeof(char), sizeof(LonelyPeople), f);
0
 Аватар для eva2326
1673 / 501 / 107
Регистрация: 17.05.2015
Сообщений: 1,519
06.06.2019, 12:33
Цитата Сообщение от zss Посмотреть сообщение
Таким способом контейнеры записывать нельзя.
Т.к. данные находятся в динамической памяти, а не внутри структуры.
Придется писать поэлементно.
Он итак по-элементно пишет:
fwrite(&ManyPeople[i], sizeof(LonelyPeople), sizeof(ManyPeople), f);
1
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,818
06.06.2019, 12:44
Лучший ответ Сообщение было отмечено Fortuno как решение

Решение

Fortuno, выше правильно заметили про размер. лучше его сохранить в начале файла.

Запись:
C++
1
2
3
4
5
    unsigned int size = ManyPeople.size();
    fwrite(&size, sizeof(char), sizeof(size), f);
    for (size_t i = 0; i < size; i++) {
        fwrite(&ManyPeople[i], sizeof(char), sizeof(LonelyPeople), f);
    }
Чтение:
C++
1
2
3
4
5
6
7
8
9
10
    unsigned int size = 0;
    fread(&size, sizeof(char), sizeof(size), f);
    for(size_t i = 0; i < size; i++)
    {
        if(feof(f)) break;
 
        LonelyPeople s;
        fread(&s, sizeof(char), sizeof(s), f);
        ManyPeople.push_back(s);
    }
Код дан для примера. Проверять ошибки не забывайте.

Добавлено через 3 минуты
Цитата Сообщение от eva2326 Посмотреть сообщение
Загружать нужно столько же, сколько было сохраненно.
На самом деле именно в его случае это не стрельнет, т.к. он в цикле дополнительно проверяет конец файла.
Хотя конечно сохранять размер все равно не помешает
2
0 / 0 / 0
Регистрация: 09.06.2013
Сообщений: 9
06.06.2019, 13:13  [ТС]
не разобрался как на сайте правильно цетировать ответы и отвечать определенным людям, отвечу как умею

zss, еще пробовал, но думаю это тоже самое что я делаю(сейчас проверю)

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

по поводу счетчика - такая конструкция тоже не работает
C++
1
2
3
4
5
6
7
    
while(!feof(f))
    {
        LonelyPeople s;
        fread(&s,sizeof(LonelyPeople),1,f);
        ManyPeople.push_back(s);
    }
DrOffset, пробовал, ошибка не пропала

Добавлено через 18 минут
Спасибо, с сохранением переменной в файле все работает, если есть другой способ без доп переменной буду рад его узнать=) если сам найду, поделюсь
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,818
06.06.2019, 13:16
Цитата Сообщение от Fortuno Посмотреть сообщение
пробовал, ошибка не пропала
Что именно пробовали?
Если вы что-то меняете в коде и оно снова не работает - измененный код надо выкладывать сюда заново, иначе только телепаты смогут помочь.

Добавлено через 1 минуту
Цитата Сообщение от Fortuno Посмотреть сообщение
счетчик будет костылем
Нет, это что угодно, но не костыль.
0
0 / 0 / 0
Регистрация: 09.06.2013
Сообщений: 9
06.06.2019, 13:43  [ТС]
про изменение, это не первое ваше сообщение где нужно было тип данных изменить с пользовательского на char

Там где код с доп переменной все работает, еще раз спасибо

Добавлено через 10 минут
Назвал костылем потому что все равно в файле будет мусору на 31-у позицию вектора. При старой загрузке в вектор, без переменной, счетчик вектора видит больше строк, значит в файле есть какие то символы на этом месте, а значит если у меня в файле будет 1000 строк из вектора то к ним будет еще 31000 непонятных символов как минимум
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,818
06.06.2019, 13:45
Цитата Сообщение от Fortuno Посмотреть сообщение
азвал костылем потому что все равно в файле будет мусору на 31-у позицию вектора. При старой загрузке в вектор, без переменной, счетчик вектора видит больше строк, значит в файле есть какие то символы на этом месте, а значит если у меня в файле будет 1000 строк из вектора то к ним будет еще 31000 непонятных символов как минимум
Ничего такого не будет, если правильно делать.
0
0 / 0 / 0
Регистрация: 09.06.2013
Сообщений: 9
06.06.2019, 14:51  [ТС]
Это если нормально делать До сохранения вектор имеет нормальный размер, а при записи в файл что то не то с форматом или с моим кодом записи в файл, но после записи в файл там сначала!(это важно) мой вектор, а уже только потом!(тоже важно) какие то символы которые программа при чтении файла определяет как новые элементы вектора и причем в числе равном количеству записей помноженном на 31 (вместе с записями получается на каждую запись 32 строки вектора при открытии файла) 3 человека уже 96 строк(или символов переноса) в файле. Или может быть файл записывается в нужном формате, а при чтении после вектора указанного вначале, он *магия* увеличивает вектор на vector.size() * 31

Добавлено через 42 минуты
DrOffset, Неловко признавать...

C++
1
fwrite(&ManyPeople[i], sizeof(char), sizeof(LonelyPeople), f);
Это решало проблему, я не заметил что вы изменили второй sizeof с ManyPeople на LonelyPeople
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,818
06.06.2019, 14:57
Цитата Сообщение от Fortuno Посмотреть сообщение
вы изменили второй sizeof с ManyPeople на LonelyPeople
Ну поэтому и изменил, чтобы
Цитата Сообщение от Fortuno Посмотреть сообщение
какие то символы которые программа при чтении файла определяет как новые элементы вектора
не появлялись. Вы же своей прежней записью писали в файл гораздо больше, чем требовалось, уже за пределами доступной вам в векторе памяти. Этот "мусор" вы и видели в файле.
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
06.06.2019, 14:57
Помогаю со студенческими работами здесь

При запуске exe файла на Windows XP, программа или не запускается или работает некорректно
Написал программу в Delphi Borland 7 на ОС Windows 7 sp1, все работает как положено. При запуске exe файла, на Windows XP, программа или не...

Открытие приложения работает некорректно (vbMinimizedNoFocus)
Доброго времени суток! Подскажите, пожалуйста, как открыть приложение, чтобы оно не перехватывало экран, а было на панели задач? Shell...

Написать текстовый редактор, в котором продемонстрировать открытие файла, сохранение файла, создание нового файла
№ 5. Написать текстовый редактор, в котором продемонстрировать открытие файла, сохранение файла, создание нового файла – чистого листа, на...

Открытие файла - запуск макроса и сохранение файла с новым именем
Пытаюсь сделать vba-программу для следующих действий: 1. открытие файла путем его выбора из окна windows; 2. запуск макроса для этого...

Сохранение и открытие файла и занесение текста файла в ListBox
Здравствуйте! Вот никак не могу понять, прочитал уже столько тем на форуме, на http://msdn.microsoft.com/, но ничего не помогает. Мне нужно...


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

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
Новые блоги и статьи
Вывод данных через динамический список в справочнике
Maks 01.04.2026
Реализация из решения ниже выполнена на примере нетипового справочника "Спецтехника" разработанного в конфигурации КА2. Задача: вывести данные из ТЧ нетипового документа. . .
Функция заполнения текстового поля в реквизите формы документа
Maks 01.04.2026
Алгоритм из решения ниже реализован на нетиповом документе "ВыдачаОборудованияНаСпецтехнику" разработанного в конфигурации КА2, в дополнении к предыдущему решению. На форме документа создается. . .
К слову об оптимизации
kumehtar 01.04.2026
Вспоминаю начало 2000-х, университет, когда я писал на Delphi. Тогда среди программистов на форумах активно обсуждали аккуратную работу с памятью: нужно было следить за переменными, вовремя. . .
Идея фильтра интернета (сервер = слой+фильтр).
Hrethgir 31.03.2026
Суть идеи заключается в том, чтобы запустить свой сервер, о чём я если честно мечтал давно и давно приобрёл книгу как это сделать. Но не было причин его запускать. Очумелые учёные напечатали на. . .
Модель здравосоХранения 6. ESG-повестка и устойчивое развитие; углублённый анализ кадрового бренда
anaschu 31.03.2026
В прикрепленном документе раздумья о том, как можно поменять модель в будущем
10 пpимет, которые всегда сбываются
Maks 31.03.2026
1. Чтобы, наконец, пришла маршрутка, надо закурить. Если сигарета последняя, маршрутка придет еще до второй затяжки даже вопреки расписанию. 2. Нaдоели зима и снег? Не надо переезжать. Достаточно. . .
Перемещение выделенных строк ТЧ из одного документа в другой
Maks 31.03.2026
Реализация из решения ниже выполнена на примере нетипового документа "ВыдачаОборудованияНаСпецтехнику" с единственной табличной частью "ОборудованиеИКомплектующие" разработанного в конфигурации КА2. . . .
Functional First Web Framework Suave
DevAlt 30.03.2026
Sauve. IO Апнулись до NET10. Из зависимостей один пакет, работает одинаково хорошо как в режиме проекта так и в интерактивном режиме. из сложностей - чисто функциональный подход. Решил. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru