Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.55/11: Рейтинг темы: голосов - 11, средняя оценка - 4.55
1373 / 596 / 199
Регистрация: 02.08.2011
Сообщений: 2,886

Как записать структуру в бинарный файл одним "блоком"

24.09.2015, 20:55. Показов 2604. Ответов 38
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Как записать структуру в бинарный файл одним "блоком", если в структуре есть private данные?

C++
1
2
3
4
5
6
7
struct MyStruct{
       char Name[20];
       void getN()  {cin>>N;}
       void showN() {cout<<N;};
   private:
       int N;
};
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
int main()
{
    const int N=3;
    MyStruct A[N];
    strcpy(A[0].Name,"Ivan");
     A[0].getN();
 
    strcpy(A[1].Name,"Wasia");
    A[1].getN();
 
    strcpy(A[2].Name,"Petrosan");
    A[2].getN();
 
   //Записать в бинарный файл
   //Прочитать из  файла в массив структур.
 
}
Есть ли для этого какие-то механизмы, трюки или хоть что-то полезное?
Как бы если структур много, а в них данных много, то запись кусочками не очень симпатична.

Интересует как C++, так и вариант с Си, но дублировать темы нельзя, поэтому об обоих языках вопрос в одной ветке.
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
24.09.2015, 20:55
Ответы с готовыми решениями:

Как записать структуру в бинарный файл и прочесть из него?
#include #include #include typedef struct tele { int nom; char fam; char im; int kols; int koly;

Как правильно записать в бинарный файл структуру, в которой есть string?
Предположим есть вот такая структура struct MyStruct { int number; string str; }; Её надо записать в бинарный файл, с...

Записать структуру в бинарный файл
ЛЮДИ подскажите кто знает,чувствую,что ответ где то рядом,а где найти не могу:( Пусть есть структура,которую надо занести в бинарный файл...

38
7804 / 6568 / 2988
Регистрация: 14.04.2014
Сообщений: 28,705
24.09.2015, 21:05
Лучший ответ Сообщение было отмечено daslex как решение

Решение

private как-то мешает записывать её целиком?
C++
1
ofs.write(reinterpret_cast<char *>(A), sizeof(MyStruct) * N);
1
1373 / 596 / 199
Регистрация: 02.08.2011
Сообщений: 2,886
24.09.2015, 21:14  [ТС]
Все норм. ничто не мешает. ) понял.
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,816
24.09.2015, 21:24
Лучший ответ Сообщение было отмечено daslex как решение

Решение

Цитата Сообщение от daslex Посмотреть сообщение
ничто не мешает
На самом деле мешает.
Если говорить в общем, то классы и структуры, в которых содержатся данные в разных секциях так записывать нельзя, потому что:
Цитата Сообщение от 9.2/13
Nonstatic data members of a (non-union) class with the same access control (Clause 11) are allocated so
that later members have higher addresses within a class object. The order of allocation of non-static data
members with different access control is unspecified
(Clause 11).
Т.е., например, если ты так запишешь структуру программой, скомпилированную одним компилятором, а прочитаешь, скомпилированной другим (или тем же, но с другими настройками), то вполне можешь получить не то, что ожидаешь.
Кроме этого ,есть еще проблема разного порядка байт (которая, впрочем, не важна, если мы не переносим такие дампы между платформами).
2
1373 / 596 / 199
Регистрация: 02.08.2011
Сообщений: 2,886
24.09.2015, 21:35  [ТС]
Т.е. так записывать можно только чистые структуры и классы, в которых абсолютно всё в одной секции, т.е. в секции public или же если абсолютно однозначно и запись и чтение будут выполнятся программой, скомпилированной в одном компиляторе с одними и теми же настройками на момент компиляции, да еще и исключительно для одной платформы?
0
7804 / 6568 / 2988
Регистрация: 14.04.2014
Сообщений: 28,705
24.09.2015, 21:39
DrOffset, это разве не о классах?
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,816
24.09.2015, 21:45
Цитата Сообщение от nmcf Посмотреть сообщение
это разве не о классах?
Написал в структуре - public/private - это уже не структура, а класс и С-шные законы на него действовать уже не обязаны.

Добавлено через 26 секунд
Цитата Сообщение от daslex Посмотреть сообщение
Т.е. так записывать можно только чистые структуры и классы, в которых абсолютно всё в одной секции, т.е. в секции public или же если абсолютно однозначно и запись и чтение будут выполнятся программой, скомпилированной в одном компиляторе с одними и теми же настройками на момент компиляции, да еще и исключительно для одной платформы?
Строго говоря, да.

Т.е. так записывать можно только чистые структуры и классы, в которых абсолютно всё в одной секции
Причем то, что в одной секции, должно быть объектами POD типов.
1
7804 / 6568 / 2988
Регистрация: 14.04.2014
Сообщений: 28,705
24.09.2015, 21:46
Ну если запись и чтение делает одна программа, то allocation должен совпадать.
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,816
24.09.2015, 21:51
Цитата Сообщение от nmcf Посмотреть сообщение
Ну если запись и чтение делает одна программа, то allocation должен совпадать.
Не должен, а может. Но, например, нет гарантий, что в одна и та же программа в debug\release вариантах не будет вести себя по-разному.
Естественно в реальности все может быть хорошо. Мы вот недавно баг исправили, который 15 лет жил и никто его не замечал, пока компилятор не обновили.
Мое дело предупредить, а вы сами решайте что с этим делать дальше.
1
7804 / 6568 / 2988
Регистрация: 14.04.2014
Сообщений: 28,705
24.09.2015, 21:55
Ну не может же одна и та же программа по разному строить одну и ту же структуру, нестыковки будут внутри.
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,816
24.09.2015, 22:02
Цитата Сообщение от nmcf Посмотреть сообщение
Ну не может же одна и та же программа по разному строить одну и ту же структуру, нестыковки будут внутри.
Это еще почему? Написано же, что порядок неопределен.
Компилятор в отладочных целях может расположить элементы в разных секциях в одном порядке, а в релизе, с максимумом оптимизации в другом - это же обычное дело.
Что толку спорить с фактами?
0
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
24.09.2015, 22:04
Цитата Сообщение от DrOffset Посмотреть сообщение
На самом деле мешает.
Если рассуждать с точки зрения совместимости бинарных данных в разных системах, то надо и порядок байтов учитывать.

Не по теме:

P.S. формально речь шла о write-only :)

Цитата Сообщение от DrOffset Посмотреть сообщение
который 15 лет жил и никто его не замечал
Значит другой баг его компенсировал, а исправив этот можно нарушить работу программы.
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,816
24.09.2015, 22:07
Цитата Сообщение от Tulosba Посмотреть сообщение
то надо и порядок байтов учитывать.
А я об этом написал же выше.

Цитата Сообщение от Tulosba Посмотреть сообщение
Значит другой баг его компенсировал, а исправив этот можно нарушить работу программы.
Его компенсировала особенность интерпретации UB компилятором. В новой версии UB cтало проявляться иначе и все сломалось

Добавлено через 1 минуту

Не по теме:

Цитата Сообщение от Tulosba Посмотреть сообщение
P.S. формально речь шла о write-only
Вот вам бы лишь бы придраться, сэр :)

0
1373 / 596 / 199
Регистрация: 02.08.2011
Сообщений: 2,886
24.09.2015, 22:09  [ТС]
Можно немного почитать о POD типах и можно увидеть нечто типа:
Чтобы быстро записать на диск сложный заголовок файла наподобие BMP, можно сформировать его в памяти, а затем записать одной командой — но структура данных, в которой формируем заголовок, также должна быть POD’ом.
Вообще не вижу смысла спорить с аргументацией DrOffset,

но моя интуиция мне говорит, что в C++11 может быть так (ну не совсем так, но некоторым подобием такого) может и можно записывать в файл. Это только догадки, ни коим образом не утверждения.
0
7804 / 6568 / 2988
Регистрация: 14.04.2014
Сообщений: 28,705
24.09.2015, 22:11
Цитата Сообщение от DrOffset Посмотреть сообщение
Компилятор в отладочных целях
Да я не об этом. Конкретный скомпилированный экземпляр программы будет использовать идентичную структуру для всех операций.
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,816
24.09.2015, 22:15
Цитата Сообщение от daslex Посмотреть сообщение
но моя интуиция мне говорит, что в C++11
Вообще моя цитата из одного из последних драфтов С++14. И, насколько я знаю, подобное ограничение всегда существовало.
Вот для сишных структур в пределах платформы ABI "стандартизировано" (но мы помним, что в сишных структурах не может быть никаких public\private), почитать можно тут.

Добавлено через 1 минуту
Цитата Сообщение от nmcf Посмотреть сообщение
Конкретный скомпилированный экземпляр программы будет использовать идентичную структуру для всех операций.
С этим никто не спорил Но это несколько эфемерная гарантия, согласись. Разве что жестко зафиксировать версию и настройки компиляторов и ни в коем случае никому другому не давать свою программу собирать из исходников.
1
7804 / 6568 / 2988
Регистрация: 14.04.2014
Сообщений: 28,705
24.09.2015, 22:18
Может, есть какие-то настройки компилятора, чтобы жёстко закрепить последовательность полей. Типа #pragma pack для выравнивания.
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,816
24.09.2015, 22:22
Цитата Сообщение от nmcf Посмотреть сообщение
Может, есть какие-то настройки компилятора, чтобы жёстко закрепить последовательность полей. Типа #pragma pack для выравнивания.
Да скорее всего есть.
Только не проще ли писать сразу корректные программы, а не искать потом костыли для того, чтобы все не сломалось?
1
Модератор
Эксперт по электронике
8981 / 6748 / 921
Регистрация: 14.02.2011
Сообщений: 23,867
24.09.2015, 22:53
Цитата Сообщение от DrOffset Посмотреть сообщение
Т.е., например, если ты так запишешь структуру программой, скомпилированную одним компилятором, а прочитаешь, скомпилированной другим (или тем же, но с другими настройками), то вполне можешь получить не то, что ожидаешь.
так это можно и на простой структуре хапнуть, разное выравнивание и все, приплыли
я бы ввел в класс метод(ы) что то типа
WriteFile ReadFile
и в них бы все и реализовал
а для корректной обработки данных от разных компиляторов, можно ввести поле версия
и при чтении проверять свой файл или нет

Добавлено через 1 минуту
Цитата Сообщение от nmcf Посмотреть сообщение
Типа #pragma pack для выравнивания.
а прагма может делать всепо другому в другом компиляторе
знаменитая MS pragma once, тому пример
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,816
24.09.2015, 22:57
Цитата Сообщение от ValeryS Посмотреть сообщение
так это можно и на простой структуре хапнуть
Можно. Но в пределах платформы (например только x86 или только x86_64, или только SPARC32 и т.д.) выравнивание не будет меняться. Там выше ссылка была.
В принципе конечно, если совсем строго подходить к вопросу, то так сохранять структуры можно только с отключенным выравниванием, с гарантией определенного порядка байт и только POD.
Но вопрос с public\private более тонкий, поэтому я высказывался подробно только о нем.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
24.09.2015, 22:57
Помогаю со студенческими работами здесь

Записать структуру в бинарный файл
Всем доброго времени суток. у меня такая проблема, мне нужно перекинуть в бинарный файл структуру. Структуру создала, все сделала. Файл...

Как правильно заполнить структуру и сохранить в бинарный файл?
Подскажите, как правильно заполнить структуру и сохранить в бинарный файл, с использованием стандартных функций C++ При такой записи: ...

Как открыть бинарный файл, не зная его структуру?
Можно ли как-нибудь открыть бинарный файл, не зная его структуру?

Как правильно сохранить и потом считать структуру в бинарный файл
Есть структура struct card { int size; char *lear; int *name; }; Эта структура это карты игрока. Заполняем ее данными, у...

Создать текстовый файл ft и в итоге записать его как бинарный файл fd
Создать текстовый файл ft, содержащий n строк по 2*m целых чисел. Считать числа из файла ft, сформировать два массива размерностью n*m из...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Символьное дифференцирование
igorrr37 13.02.2026
/ * Логарифм записывается как: (x-2)log(x^2+2) - означает логарифм (x^2+2) по основанию (x-2). Унарный минус обозначается как ! */ #include <iostream> #include <stack> #include <cctype>. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL3_image
8Observer8 10.02.2026
Содержание блога Библиотека SDL3_image содержит инструменты для расширенной работы с изображениями. Пошагово создадим проект для загрузки изображения формата PNG с альфа-каналом (с прозрачным. . .
Установка Qt-версии Lazarus IDE в Debian Trixie Xfce
volvo 10.02.2026
В общем, достали меня глюки IDE Лазаруса, собранной с использованием набора виджетов Gtk2 (конкретно: если набирать текст в редакторе и вызвать подсказку через Ctrl+Space, то после закрытия окошка. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru