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

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

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

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

15.05.2012, 12:49. Просмотров 841. Ответов 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
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
15.05.2012, 12:49
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Странности с чтением объекта структуры из файла (C++):

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

Ошибка с чтением файла - C++
Привет, у меня тут проблема. Я сделал программу, которая открывает файл и выводит содержимое на экран, но если я вывожу содержимое второй...

Проблема с чтением из файла! - C++
Проблема такая: у меня есть текстовый файл, в котором на каждой новой строке написано число. Я хочу каждое из этих чисел присвоить массиву...

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

Проблема с чтением файла - C++
При открытии файла функцией fopen и выводе на консоль отображается только первая строчка. Я так понял что надо открыть файл как бинарный....

Чтением файла с сервера - C++
Всем привет, столкнулся с ошибкой, но сам не знаю где... Суть программы такова: При запуске программы должен отправляться запрос на...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
zss
Модератор
Эксперт С++
6380 / 5945 / 1927
Регистрация: 18.12.2011
Сообщений: 15,264
Завершенные тесты: 1
15.05.2012, 12:57 #2
Может быть файл не закрывается?
попробуйте вставить
fclose(in);
0
Gepar
1177 / 533 / 20
Регистрация: 01.07.2009
Сообщений: 3,517
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'ами это дело решать, ато фигня просиходит.
0
zss
Модератор
Эксперт С++
6380 / 5945 / 1927
Регистрация: 18.12.2011
Сообщений: 15,264
Завершенные тесты: 1
15.05.2012, 13:33 #4
С трудом, но нашел!!!
C++
1
2
 //fwrite(&it,sizeof(Item),1,out);
 fwrite(it,sizeof(Item),1,out);
и fread аналогично
1
Gepar
1177 / 533 / 20
Регистрация: 01.07.2009
Сообщений: 3,517
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, ну я методом тыка определил что оно так хочет видеть. Осталась проблема с удалением ну или сдвигом куска файла чтобы одну из записей можно было затирать.
0
go
Эксперт C++
3586 / 1366 / 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 вызывать?
1
Герц
524 / 341 / 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 или подобных.
0
go
Эксперт C++
3586 / 1366 / 128
Регистрация: 16.04.2009
Сообщений: 4,528
15.05.2012, 14:29 #8
Цитата Сообщение от Герц Посмотреть сообщение
Ничто не мешает читать файл, открытый в text-mode, с помощью fread, а не getc, gets или подобных.
Если файл открыт в текстовом режиме, каждый символ возврата каретки CR заменяется на два символа - возврата каретки CR и перевода строки LF.
Как видите нюансы есть. Тогда возникает вопрос: зачем?
0
Герц
524 / 341 / 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
Так что у Вас неверные сведения.
0
go
Эксперт C++
3586 / 1366 / 128
Регистрация: 16.04.2009
Сообщений: 4,528
15.05.2012, 14:54 #10
Цитата Сообщение от Герц Посмотреть сообщение
Про эти "нюансы" я и без Вас знаю, не понятно, чем они Вам помешали при чтении с fread :-)
Так а как данные записал то в файл? Небось ТС открыл файл в блокноте, и ручками вводил

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

Не по теме:

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

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

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

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

Вынос мозга с чтением файла - C++
Здравствуйте. К моему сожалению облазив Яндекс и Гугл, я не смог найти решения проблемы и поэтому вынужден просить помощи у вас. ...

Матрица с чтением функции из файла - C++
Составил тут программу по лабораторной: #include&lt;fstream&gt; #include&lt;iostream&gt; #include&lt;iomanip&gt; #include&lt;math.h&gt; using namespace...


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
17.05.2012, 16:00
Ответ Создать тему
Опции темы

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