Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.50/6: Рейтинг темы: голосов - 6, средняя оценка - 4.50
 Аватар для Gepar
1186 / 543 / 78
Регистрация: 01.07.2009
Сообщений: 3,517

Странности с чтением объекта структуры из файла

15.05.2012, 12:49. Показов 1329. Ответов 12
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Почему-то возникают проблемы с чтением объектов структуры из файла.
Структура
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
struct Item
{
    Item(int k,const char* ch, Item* n=NULL)
    :key(k),info(new char[strlen(ch)+1]),next(n)
    {
        strcpy(info,ch);
        length=strlen(info)+1;
    }
    int key;
    char* info;
    Item* next;
    int shift;
    int length;
};
Функция где я записываю объект структуры и тут же считываю его. Работает правильно:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
void Test()
{
    Item* it,*it2;
    it2=new Item(1,"anyway");//в этот объект я буду читать из файла. Он должен изменится!
 
    it= new Item(100500,"t");//этот объект я хочу записать в файл
    it->shift=200;
    it->length=2;
 
    FILE* out=fopen("out.txt","r+");
    if(!out)
     cerr<<"Can't open file\n";
 
    fwrite(&it,sizeof(Item),1,out);
    fclose(out);
 
    FILE* in=fopen("out.txt","r");
    if(!in)
     cerr<<"Can't open file\n";
    fread(&it2,sizeof(Item),1,in);
    cout<<it2->key;//key = 100500 что правильно
}
А теперь чудеса. После запуска этой функции у меня ведь остался файл out.txt где осталась эта одна запись объекта стрктуры. Я засовываю в комментарии теперь тот код где я пишу объект структуры и пытаюсь сразу считать её и о чудо - получаю сегфолт.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
void Test()
{
    Item* it,*it2;
    it2=new Item(1,"anyway");//в этот объект я буду читать из файла. Он должен изменится!
    /*
    it= new Item(100500,"t");//этот объект я хочу записать в файл
    it->shift=200;
    it->length=2;
 
    FILE* out=fopen("out.txt","r+");
    if(!out)
     cerr<<"Can't open file\n";
 
    fwrite(&it,sizeof(Item),1,out);
    fclose(out);
    */
 
    FILE* in=fopen("out.txt","r");
    if(!in)
     cerr<<"Can't open file\n";
    fread(&it2,sizeof(Item),1,in);
    cout<<it2->key;// тут программа вылетает
}
Помогите пожалуйста, не логично оно (с моей стороны) получается. Может я что забыл о сишной работе с файлами.
P.S Да, я в курсе что всё на то что указывают указатели нужно писать отдельно и что оно так как я сейчас делаю не запишеться, но я хочу чтобы писался и читался каркас - обычные поля (не указатели) моей структуры.

Добавлено через 2 часа 38 минут
Из любопытного ещё:
vs2010 даёт вывести ключ что в it2 и он считан правильно, но после этой строчки vs говорит что стеку не хорошо
"Run-Time Check Failure #2 - Stack around the variable 'it' was corrupted."
Что же делать? Собственно задача писать эту стркутуру через fwrite и читать через fread в бинарник. Как же я по другому её решу.
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
15.05.2012, 12:49
Ответы с готовыми решениями:

Проблема с чтением структуры из файла бинарного типа
Public Type TestRecord ''Total=32 A As Long ''4 B As String * 2 ...

Структуры. Объем занимаемой памяти. Небольшие странности в арифметике
Вот имеется у меня такой код #include &lt;stdio.h&gt; #include &lt;stdlib.h&gt; struct pupil{ char sn; int marks; }; typedef struct pupil...

Передача структуры в функцию по значению. Странности компилятора под ARM
Есть коссплаформенный код(сразу скажу абсолютно рабочий на x86 и скорее всего других плаформах, кроме ARM): */ typedef struct...

12
Модератор
Эксперт С++
 Аватар для zss
13773 / 10966 / 6491
Регистрация: 18.12.2011
Сообщений: 29,245
15.05.2012, 12:57
Может быть файл не закрывается?
попробуйте вставить
fclose(in);
0
 Аватар для Gepar
1186 / 543 / 78
Регистрация: 01.07.2009
Сообщений: 3,517
15.05.2012, 13:24  [ТС]
zss, да нет, я ведь ключ пытаюсь распечатать пока файл открыт. Что-то оно вообще фигня полная происходит с этой fread. Гоняю в дебагере этот код и что я вижу
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
void Test()
{
    Item* it=NULL,*it2;
    it2=new Item;//в этот объект я буду читать из файла. Он должен изменится!
    /*
    it= new Item(100500,"t");//этот объект я хочу записать в файл
    it->shift=200;
    it->length=2;
 
    FILE* out=fopen("out.txt","r+");
    if(!out)
     cerr<<"Can't open file\n";
 
    fwrite(&it,sizeof(Item),1,out);
    fclose(out);
    */
 
    FILE* in=fopen("out.txt","r");
    if(!in)
     cerr<<"Can't open file\n";
    fread(&it2,sizeof(Item),1,in); //после этой строчки меняется адрес у it и it2. Обратите внимание, до этого it=NULL
    //и нигде не используется на протяжении всей функции. Как эта сраная сишная fread до неё добралась и изменила указатель ???
    cout<<it2->key;//сегфолт, всё потому что it2 указывает не пойми на что. 
   //Fread после того как в неё читала данные изменила адрес на какой-то кусок памяти к которому видать доступа то и нет.
}
Добавлено через 7 минут
Как эти fread и fwrite вообще работают то? Может я всё же не правильно им передаю что писать/читать? Им адрес надо давать объекта стркутуры, или указатель на него или адрес указателя ? Они же всё принимают и угадывай потом что оно записало, а что считало.

Добавлено через 5 минут
Наверное надо пробовать с malloc'ами это дело решать, ато фигня просиходит.
0
Модератор
Эксперт С++
 Аватар для zss
13773 / 10966 / 6491
Регистрация: 18.12.2011
Сообщений: 29,245
15.05.2012, 13:33
С трудом, но нашел!!!
C++
1
2
 //fwrite(&it,sizeof(Item),1,out);
 fwrite(it,sizeof(Item),1,out);
и fread аналогично
1
 Аватар для Gepar
1186 / 543 / 78
Регистрация: 01.07.2009
Сообщений: 3,517
15.05.2012, 13:58  [ТС]
Через malloc вроде более-менее вменяемо читает. По крайней мере чудес тем что читаешь в один указатель, а меняется другой теперь нет.

Остаётся одна проблема: мне нужно в бинарник отдельно писать строки char (длину и сдвиг я буду знать для каждой из строк), как мне при необходимости потом удалять такие строки? Ну вот пример:
есть у меня 3 строки: "string1." , "string2." и "string3.". Все они в файле в бинарном виде записаны примерно так "string1.string2.stirng3." Мне нужно удалить "string2.". Я знаю сдвиг до неё (8*sizeof(char)). Как теперь удалить её так чтобы получилась строка "string1.string3." ? Временный файл куда всё это будет переписываться, а потом удаляться оригинал и временный называться как положено заводить не хотелось бы.

Добавлено через 2 минуты
zss, ну я методом тыка определил что оно так хочет видеть. Осталась проблема с удалением ну или сдвигом куска файла чтобы одну из записей можно было затирать.

Добавлено через 2 минуты
zss, ну я методом тыка определил что оно так хочет видеть. Осталась проблема с удалением ну или сдвигом куска файла чтобы одну из записей можно было затирать.
0
go
Эксперт С++
3646 / 1378 / 243
Регистрация: 16.04.2009
Сообщений: 4,526
15.05.2012, 14:10
Цитата Сообщение от Gepar Посмотреть сообщение
FILE* in=fopen("out.txt","r");
if(!in)
cerr<<"Can't open file\n";
fread(&it2,sizeof(Item),1,in);
Классно Вы читаете. Открыли текстовый файл в текстовом режиме, так с чего это fread вызывать?
1
545 / 344 / 12
Регистрация: 05.11.2010
Сообщений: 1,076
Записей в блоге: 1
15.05.2012, 14:18
Я бы реализовал операции с файлами через сериализацию Item, преобразовывая Item* в char* и наоборот.
C++
1
2
3
4
5
6
char tmp[ sizeof( Item ) ];
Item* item = new Item(...);
fwrite( (char*)item, sizeof( Item ), 1, file );
//
fread( tmp, sizeof( Item), 1, file );
Item* anotherItem  = (Item*)tmp;
Кстати да, для записи структуры в файл и чтения её оттуда стоит использовать бинарный режим, иначе сохраняйте свою структуру в какой-нибудь xml или json.
Классно Вы читаете. Открыли текстовый файл в текстовом режиме, так с чего это fread вызывать?
Ничто не мешает читать файл, открытый в text-mode, с помощью fread, а не getc, gets или подобных.
0
go
Эксперт С++
3646 / 1378 / 243
Регистрация: 16.04.2009
Сообщений: 4,526
15.05.2012, 14:29
Цитата Сообщение от Герц Посмотреть сообщение
Ничто не мешает читать файл, открытый в text-mode, с помощью fread, а не getc, gets или подобных.
Если файл открыт в текстовом режиме, каждый символ возврата каретки CR заменяется на два символа - возврата каретки CR и перевода строки LF.
Как видите нюансы есть. Тогда возникает вопрос: зачем?
0
545 / 344 / 12
Регистрация: 05.11.2010
Сообщений: 1,076
Записей в блоге: 1
15.05.2012, 14:36
Про эти "нюансы" я и без Вас знаю, не понятно, чем они Вам помешали при чтении с fread :-)
Кстати:
If the given stream is opened in text mode, carriage return–linefeed pairs are replaced with single linefeed characters.
http://msdn.microsoft.com/en-u... etdcs.aspx
Так что у Вас неверные сведения.
0
go
Эксперт С++
3646 / 1378 / 243
Регистрация: 16.04.2009
Сообщений: 4,526
15.05.2012, 14:54
Цитата Сообщение от Герц Посмотреть сообщение
Про эти "нюансы" я и без Вас знаю, не понятно, чем они Вам помешали при чтении с fread :-)
Так а как данные записал то в файл? Небось ТС открыл файл в блокноте, и ручками вводил

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

Не по теме:

Цитата Сообщение от Герц Посмотреть сообщение
Так что у Вас неверные сведения.
Читайте между строк :)

0
 Аватар для Gepar
1186 / 543 / 78
Регистрация: 01.07.2009
Сообщений: 3,517
15.05.2012, 18:00  [ТС]
Цитата Сообщение от go Посмотреть сообщение
Так а как данные записал то в файл? Небось ТС открыл файл в блокноте, и ручками вводи
Не знаю, файл читается и пишется нормально если fread куски памяти выделенные malloc'ом подсовывать, а не new. Другое дело в том как реализовать сдвиг, да и как вообще лучше всего сделать. От меня чего хотят: список этих стркутур хранить в файле. Но не просто хранить, хранить хитро: таблицу (всё кроме поля info) читать и записывать в начале и в конце работы с ней, а данные (поле char* info) записывать в файл сразу же. Собственно из-за этого и куча проблем:
1) Записали размер таблицы, записали таблицу, записали данные, всё хорошо.
2)Считали таблицу всё хорошо. Добавили элемент -> пишем в файл, таблица увеличилась - беда-беда данные нужно сдвинуть. Беда-беда данные сдвинули, а в таблице же ссылки на данные без сдвига, перебираем всю таблицу, меняем сдвиги, фух. Вроде всё.
3)Считали таблицу -> удалили элемент. Беда-беда. Длина таблицы уменьшилась. Беда-беда, элемент удалили первый, а у нас их там ещё на 3 мегабайта после него записано, что делать, как двигать.
Чтобы всё ещё сложнее казалось работать надо черезе этот тупой сишный FILE* с его сишной манерой работы да сишными ошибками. В общем ужас.
0
Модератор
Эксперт С++
 Аватар для zss
13773 / 10966 / 6491
Регистрация: 18.12.2011
Сообщений: 29,245
17.05.2012, 14:47
Цитата Сообщение от Gepar Посмотреть сообщение
Беда-беда. Длина таблицы уменьшилась...
Проблему можно решить, если воспользоваться двумя файлами.
В один пишем заголовки, а в другой содержимое.
0
 Аватар для Gepar
1186 / 543 / 78
Регистрация: 01.07.2009
Сообщений: 3,517
17.05.2012, 16:00  [ТС]
zss, да это логично, я бы так сделал будь задание "реализовать вводи и вывод данных в файл". А тут ведь препод считает себя умнее всех и не даёт места для творчества вот и пишет как это нужно делать пошагово что именно в файл и что именно таблица сохраняется в конце, а инфо сразу... хотя я вот думаю запилить всё же как это удобно мне (сразу сохранять и таблицу и инфо + читать в начале сразу таблицу вместе с инфо в оп), может препод не сильно будет придираться, ато с этими сдвигами уж слишком много проблем возникает.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
17.05.2012, 16:00
Помогаю со студенческими работами здесь

чтением из файла....
у меня есть два класса... один (базовый) читает строку из файла и присваивает её значение переменной этого типа второй (производный)...

Ошибка с чтением файла
Добрый вечер, ниже реализована программа по обработке файла данных &quot; Репертуар кинотеатров&quot; в котором указаны название кинотеатра и...

Проблемы с чтением файла на c++
Задача: Сформировать массив данных с помощью структуры. Предметная область – данные о студентах имеющих публикации (номер по порядку,...

Проблема с чтением из файла
Подскажите пожалуйста в чем ошибка? Чтения не происходит. Нули в массиве как были, так и остаются. первый раз работаю в Visual, может быть...

Проблемы с чтением из файла
Здравствуйте все! У меня сразу два вопроса. Начну с того, который попроще. Я осваиваю библиотеку fstream, решил написать небольшой кусочек...


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

Или воспользуйтесь поиском по форуму:
13
Ответ Создать тему
Новые блоги и статьи
Автозаполнение реквизита при выборе элемента справочника
Maks 27.03.2026
Программный код из решения ниже на примере нетипового документа "ЗаявкаНаРемонтСпецтехники" разработанного в конфигурации КА2. При выборе "Спецтехники" (Тип Справочник. Спецтехника), заполняется. . .
Сумматор с применением элементов трёх состояний.
Hrethgir 26.03.2026
Тут. https:/ / fips. ru/ EGD/ ab3c85c8-836d-4866-871b-c2f0c5d77fbc Первый документ красиво выглядит, но без схемы. Это конечно не даёт никаких плюсов автору, но тем не менее. . . всё может быть. . .
Автозаполнение реквизитов при создании документа
Maks 26.03.2026
Программный код из решения ниже размещается в модуле объекта документа, в процедуре "ПриСозданииНаСервере". Алгоритм проверки заполнения реализован для исключения перезаписи значения реквизита,. . .
Команды формы и диалоговое окно
Maks 26.03.2026
1. Команда формы "ЗаполнитьЗапчасти". Программный код из решения ниже на примере нетипового документа "ЗаявкаНаРемонтСпецтехники" разработанного в конфигурации КА2. В качестве источника данных. . .
Кому нужен AOT?
DevAlt 26.03.2026
Решил сделать простой ланчер Написал заготовку: dotnet new console --aot -o UrlHandler var items = args. Split(":"); var tag = items; var id = items; var executable = args;. . .
Отправка уведомления на почту при создании или изменении элементов справочника
Maks 24.03.2026
Программная отправка письма электронной почты на примере типового справочника "Склады" в конфигурации БП3. Перед реализацией необходимо выполнить настройку системной учетной записи электронной. . .
модель ЗдравоСохранения 5. Меньше увольнений- больше дохода!
anaschu 24.03.2026
Теперь система здравосохранения уменьшает количество увольнений. 9TO2GP2bpX4 a42b81fb172ffc12ca589c7898261ccb/ https:/ / rutube. ru/ video/ a42b81fb172ffc12ca589c7898261ccb/ Слева синяя линия -. . .
Midnight Chicago Blues
kumehtar 24.03.2026
Такой Midnight Chicago Blues, знаешь?. . Когда вечерние улицы становятся ночными, а ты не можешь уснуть. Ты идёшь в любимый старый бар, и бармен наливает тебе виски. Ты смотришь на пролетающие. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru