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

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

06.06.2019, 11:58. Показов 2347. Ответов 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
13771 / 10964 / 6491
Регистрация: 18.12.2011
Сообщений: 29,241
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,518
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
19497 / 10102 / 2461
Регистрация: 30.01.2014
Сообщений: 17,808
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,518
06.06.2019, 12:33
Цитата Сообщение от zss Посмотреть сообщение
Таким способом контейнеры записывать нельзя.
Т.к. данные находятся в динамической памяти, а не внутри структуры.
Придется писать поэлементно.
Он итак по-элементно пишет:
fwrite(&ManyPeople[i], sizeof(LonelyPeople), sizeof(ManyPeople), f);
1
19497 / 10102 / 2461
Регистрация: 30.01.2014
Сообщений: 17,808
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
19497 / 10102 / 2461
Регистрация: 30.01.2014
Сообщений: 17,808
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
19497 / 10102 / 2461
Регистрация: 30.01.2014
Сообщений: 17,808
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
19497 / 10102 / 2461
Регистрация: 30.01.2014
Сообщений: 17,808
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
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 02.02.2026
Содержание блога Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 01.02.2026
Содержание блога В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
SDL3 для Web (WebAssembly): Установка Emscripten SDK (emsdk) и CMake для сборки C и C++ приложений в Wasm
8Observer8 30.01.2026
Содержание блога Для того чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. . . .
SDL3 для Android: Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
Инструменты COM: Сохранение данный из VARIANT в файл и загрузка из файла в VARIANT
bedvit 28.01.2026
Сохранение базовых типов COM и массивов (одномерных или двухмерных) любой вложенности (деревья) в файл, с возможностью выбора алгоритмов сжатия и шифрования. Часть библиотеки BedvitCOM Использованы. . .
SDL3 для Android: Загрузка PNG с альфа-каналом с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 28.01.2026
Содержание блога SDL3 имеет собственные средства для загрузки и отображения PNG-файлов с альфа-каналом и базовой работы с ними. В этой инструкции используется функция SDL_LoadPNG(), которая. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru