357 / 260 / 105
Регистрация: 28.04.2015
Сообщений: 1,604
1

Запись структуры (в ней есть поля типа данных char*) в бинарный файл

29.10.2016, 17:43. Показов 3574. Ответов 6
Метки нет (Все метки)

Всем привет!
Есть такая структура:
C++
1
2
3
4
5
6
7
struct Telem
{
    int key;
    char *mark;
    float engine;
    char *color;
};
В функции main() вводится информация с клавиатуры и происходит запись в бинарный файл:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
    FILE *f = fopen("d:\\telem.bin", "wb+");
    Telem tmp;
    for(int i = 1; i <= 2; i++)
    {
        tmp.key = i;
        cout << "Введите марку: ";
        tmp.mark = new char[100];
        gets(tmp.mark);
        cout << "Введите объем двигателя: ";
        cin >> tmp.engine;
        fflush(stdin);
        cout << "Введите цвет: ";
        tmp.color = new char[100];
        gets(tmp.color);
        fwrite(&tmp, sizeof(Telem), 1, f);
        cout << endl << endl;
    }
    fclose(f);
Есть функция, которая читает информацию из бинарного файла:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void ReadFile(void)
{
    Telem tmp;
    tmp.mark = new char[100];
    tmp.color = new char[100];
    FILE *f = fopen("d:\\telem.bin", "rb");
    while(fread(&tmp, sizeof(Telem), 1, f) != 0)
    {
        cout << tmp.key << endl;
        cout << tmp.mark << endl;
        cout << tmp.engine << endl;
        cout << tmp.color << endl << endl;
    }
    fclose(f);
}
Возникла такая проблема, что если ввести данные с клавиатуры, записать их в бин.файл и сразу, не закрывая программы вызвать функцию ReadFile(), то все прекрасно отрабатывает.
А вот если ввести данные с клавиатуры, записать их в бин.файл. Закрыть программу. Потом повторно запустить и только попытаться считать их из файла, то происходит крах.

Не могу понять, в чем тут подводный камень?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
29.10.2016, 17:43
Ответы с готовыми решениями:

Запись/чтение структуры с полем типа String в бинарный файл
Доброго времени суток. Есть слудующая структура struct R { int Number; String Name;...

структуры данных запись и сохранить ответ в файл типа .txt
Нужно выполнить задачу с использованием структуры данных запись и сохранить ответ в файл типа .txt....

Запись массива char в бинарный файл
Привет. Есть структура вида struct st { int id; char name; }; В поле name пишется...

Запись структуры в бинарный файл
Добрый вечере,народ. Нужна функция,которая будет записывать структуру в бинарный файл.То есть...

6
Модератор
Эксперт С++
12460 / 10018 / 6031
Регистрация: 18.12.2011
Сообщений: 26,822
29.10.2016, 18:33 2
В файл Вы пишете только содержимое структуры, т.е. вместо значений mark и color пишутся УКАЗАТЕЛИ на выделенные данные.
Их нужно писать дополнительно (и читать).
0
357 / 260 / 105
Регистрация: 28.04.2015
Сообщений: 1,604
29.10.2016, 18:41  [ТС] 3
спс zss, но давайте кое-что уточним.
вообще, я неплохо знаю базовый С++, но давно не работал с бинарными файлами и вот, результат на лицо.

Значением указателя является адрес того участка памяти, на который он ссылается/указывает.
Когда происходит динамическое выделение памяти:
C++
1
tmp.mark = new char[100];
то значением tmp.mark является некий адрес (пусть для простоты А12). Затем по этому адресу записывается информация вводом с клавиатуры.
Когда происходит вызов fwrite, то вместо марки в файл пишется А12. Это понятно.
Если программа не закрывается и происходит считывание из файла, то в поле mark записывается адрес А12 (а в этом участке памяти "лежит" словесное значение марки). Т е в таком варианте работает все ок.

При повторном запуске, когда происходит ТОЛЬКО считывание из файла, в поле mark записывается значение адреса А12, но при этом данный участок памяти уже не принадлежит структуре в общем и полю mark в частности, поэтому при попытке вывести значение марки на экран генерируется ошибка (типа violetion). Примерно так, да?
0
nd2
3431 / 2810 / 1249
Регистрация: 29.01.2016
Сообщений: 9,426
29.10.2016, 18:59 4
Цитата Сообщение от FasterHarder Посмотреть сообщение
Примерно так, да?
Примерно так. И не нужно вот это использовать для очистки буфера ввода:
Цитата Сообщение от FasterHarder Посмотреть сообщение
fflush(stdin);
Не везде будет работать. Это предназначено для очистки буфера вывода.

Добавлено через 1 минуту
И лучше не мешать в кучу ввод/вывод Си и С++.
0
357 / 260 / 105
Регистрация: 28.04.2015
Сообщений: 1,604
29.10.2016, 19:06  [ТС] 5
Последнее уточнение!
Если исправить объявление поля char *mark в рамках структуры на char mark[100], то все те же проблемы сохраняются, да?
P.S. Ведь имя статического массива - это КОНСТАНТНЫЙ указатель на неконстантные данные. Т е фактически mark является ссылкой/указателем на первый элемент символьного массива

всем спс. за помощь

Добавлено через 3 минуты
И еще вопрос: если нельзя записать fwrite() целых структурный элемент, содержащий поля-указатели, то как это делать? Писать по отдельности каждое поле (через какой-нибудь fprintf(...), использовать fwrite() для каждого поля или скомпоновать все поля-неуказатели в отдельную структуру, а указатели записывать в файл по одиночке?

P.S. потоки fstream не используются
0
nd2
3431 / 2810 / 1249
Регистрация: 29.01.2016
Сообщений: 9,426
29.10.2016, 19:15 6
Цитата Сообщение от FasterHarder Посмотреть сообщение
Цитата Сообщение от FasterHarder Посмотреть сообщение
Если исправить объявление поля char *mark в рамках структуры на char mark[100], то все те же проблемы сохраняются, да?
Нет. Тогда в структуре у тебя будет массив находится, а не указатель.

Добавлено через 3 минуты
Сделай sizeof() структуры с указателем и с массивом, и почувствуй разницу.
0
357 / 260 / 105
Регистрация: 28.04.2015
Сообщений: 1,604
29.10.2016, 19:26  [ТС] 7
Я прогнал на статических массивах - все норм. отработало!
Это ведь специфика строк такого формата в языке СИ, например, т к для типов данных int, char, float, etc нужно внутрях scanf() ставить &, а для символьных стат.массивов нет!
Тут тоже самое. В файл будет писаться само значение, а не адрес 1-го элемента.

В общем, вроде разобрался! Всем спс.
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
29.10.2016, 19:26
Помогаю со студенческими работами здесь

Запись структуры в бинарный файл
Пишу будильник, использую статический массив структур, по нажатию кнопки элемент массива должен...

Запись структуры в бинарный файл
Привет всем, тут такая проблема, мне нужно записать в бинарный файл структуру, а потом считать её....

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

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


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

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2022, CyberForum.ru