Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Gepar
1175 / 531 / 20
Регистрация: 01.07.2009
Сообщений: 3,516
#1

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

15.05.2012, 12:49. Просмотров 821. Ответов 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 в бинарник. Как же я по другому её решу.
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
zss
Модератор
Эксперт С++
6190 / 5793 / 1875
Регистрация: 18.12.2011
Сообщений: 14,799
Завершенные тесты: 1
15.05.2012, 12:57     Странности с чтением объекта структуры из файла #2
Может быть файл не закрывается?
попробуйте вставить
fclose(in);
Gepar
1175 / 531 / 20
Регистрация: 01.07.2009
Сообщений: 3,516
15.05.2012, 13:24  [ТС]     Странности с чтением объекта структуры из файла #3
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'ами это дело решать, ато фигня просиходит.
zss
Модератор
Эксперт С++
6190 / 5793 / 1875
Регистрация: 18.12.2011
Сообщений: 14,799
Завершенные тесты: 1
15.05.2012, 13:33     Странности с чтением объекта структуры из файла #4
С трудом, но нашел!!!
C++
1
2
 //fwrite(&it,sizeof(Item),1,out);
 fwrite(it,sizeof(Item),1,out);
и fread аналогично
Gepar
1175 / 531 / 20
Регистрация: 01.07.2009
Сообщений: 3,516
15.05.2012, 13:58  [ТС]     Странности с чтением объекта структуры из файла #5
Через malloc вроде более-менее вменяемо читает. По крайней мере чудес тем что читаешь в один указатель, а меняется другой теперь нет.

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

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

Добавлено через 2 минуты
zss, ну я методом тыка определил что оно так хочет видеть. Осталась проблема с удалением ну или сдвигом куска файла чтобы одну из записей можно было затирать.
go
Эксперт C++
3585 / 1365 / 128
Регистрация: 16.04.2009
Сообщений: 4,528
15.05.2012, 14:10     Странности с чтением объекта структуры из файла #6
Цитата Сообщение от Gepar Посмотреть сообщение
FILE* in=fopen("out.txt","r");
if(!in)
cerr<<"Can't open file\n";
fread(&it2,sizeof(Item),1,in);
Классно Вы читаете. Открыли текстовый файл в текстовом режиме, так с чего это fread вызывать?
Герц
523 / 340 / 4
Регистрация: 05.11.2010
Сообщений: 1,077
Записей в блоге: 1
15.05.2012, 14:18     Странности с чтением объекта структуры из файла #7
Я бы реализовал операции с файлами через сериализацию 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 или подобных.
go
Эксперт C++
3585 / 1365 / 128
Регистрация: 16.04.2009
Сообщений: 4,528
15.05.2012, 14:29     Странности с чтением объекта структуры из файла #8
Цитата Сообщение от Герц Посмотреть сообщение
Ничто не мешает читать файл, открытый в text-mode, с помощью fread, а не getc, gets или подобных.
Если файл открыт в текстовом режиме, каждый символ возврата каретки CR заменяется на два символа - возврата каретки CR и перевода строки LF.
Как видите нюансы есть. Тогда возникает вопрос: зачем?
Герц
523 / 340 / 4
Регистрация: 05.11.2010
Сообщений: 1,077
Записей в блоге: 1
15.05.2012, 14:36     Странности с чтением объекта структуры из файла #9
Про эти "нюансы" я и без Вас знаю, не понятно, чем они Вам помешали при чтении с 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-us/library/kt0etdcs.aspx
Так что у Вас неверные сведения.
go
Эксперт C++
3585 / 1365 / 128
Регистрация: 16.04.2009
Сообщений: 4,528
15.05.2012, 14:54     Странности с чтением объекта структуры из файла #10
Цитата Сообщение от Герц Посмотреть сообщение
Про эти "нюансы" я и без Вас знаю, не понятно, чем они Вам помешали при чтении с fread :-)
Так а как данные записал то в файл? Небось ТС открыл файл в блокноте, и ручками вводил

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

Не по теме:

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

Gepar
1175 / 531 / 20
Регистрация: 01.07.2009
Сообщений: 3,516
15.05.2012, 18:00  [ТС]     Странности с чтением объекта структуры из файла #11
Цитата Сообщение от go Посмотреть сообщение
Так а как данные записал то в файл? Небось ТС открыл файл в блокноте, и ручками вводи
Не знаю, файл читается и пишется нормально если fread куски памяти выделенные malloc'ом подсовывать, а не new. Другое дело в том как реализовать сдвиг, да и как вообще лучше всего сделать. От меня чего хотят: список этих стркутур хранить в файле. Но не просто хранить, хранить хитро: таблицу (всё кроме поля info) читать и записывать в начале и в конце работы с ней, а данные (поле char* info) записывать в файл сразу же. Собственно из-за этого и куча проблем:
1) Записали размер таблицы, записали таблицу, записали данные, всё хорошо.
2)Считали таблицу всё хорошо. Добавили элемент -> пишем в файл, таблица увеличилась - беда-беда данные нужно сдвинуть. Беда-беда данные сдвинули, а в таблице же ссылки на данные без сдвига, перебираем всю таблицу, меняем сдвиги, фух. Вроде всё.
3)Считали таблицу -> удалили элемент. Беда-беда. Длина таблицы уменьшилась. Беда-беда, элемент удалили первый, а у нас их там ещё на 3 мегабайта после него записано, что делать, как двигать.
Чтобы всё ещё сложнее казалось работать надо черезе этот тупой сишный FILE* с его сишной манерой работы да сишными ошибками. В общем ужас.
zss
Модератор
Эксперт С++
6190 / 5793 / 1875
Регистрация: 18.12.2011
Сообщений: 14,799
Завершенные тесты: 1
17.05.2012, 14:47     Странности с чтением объекта структуры из файла #12
Цитата Сообщение от Gepar Посмотреть сообщение
Беда-беда. Длина таблицы уменьшилась...
Проблему можно решить, если воспользоваться двумя файлами.
В один пишем заголовки, а в другой содержимое.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
17.05.2012, 16:00     Странности с чтением объекта структуры из файла
Еще ссылки по теме:

C++ Не могу разобраться с чтением из файла
C++ Матрица с чтением функции из файла
Работа с чтением/записью бинарного файла C++
C++ Ошибка с чтением файла
C++ Ошибка с чтением файла

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

Или воспользуйтесь поиском по форуму:
Gepar
1175 / 531 / 20
Регистрация: 01.07.2009
Сообщений: 3,516
17.05.2012, 16:00  [ТС]     Странности с чтением объекта структуры из файла #13
zss, да это логично, я бы так сделал будь задание "реализовать вводи и вывод данных в файл". А тут ведь препод считает себя умнее всех и не даёт места для творчества вот и пишет как это нужно делать пошагово что именно в файл и что именно таблица сохраняется в конце, а инфо сразу... хотя я вот думаю запилить всё же как это удобно мне (сразу сохранять и таблицу и инфо + читать в начале сразу таблицу вместе с инфо в оп), может препод не сильно будет придираться, ато с этими сдвигами уж слишком много проблем возникает.
Yandex
Объявления
17.05.2012, 16:00     Странности с чтением объекта структуры из файла
Ответ Создать тему
Опции темы

Текущее время: 19:36. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru