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

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

15.05.2012, 12:49. Показов 1306. Ответов 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
13771 / 10964 / 6491
Регистрация: 18.12.2011
Сообщений: 29,241
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
13771 / 10964 / 6491
Регистрация: 18.12.2011
Сообщений: 29,241
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
13771 / 10964 / 6491
Регистрация: 18.12.2011
Сообщений: 29,241
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
Ответ Создать тему
Новые блоги и статьи
http://iceja.net/ математические сервисы
iceja 20.01.2026
Обновила свой сайт http:/ / iceja. net/ , приделала Fast Fourier Transform экстраполяцию сигналов. Однако предсказывает далеко не каждый сигнал (см ограничения http:/ / iceja. net/ fourier/ docs ). Также. . .
http://iceja.net/ сервер решения полиномов
iceja 18.01.2026
Выкатила http:/ / iceja. net/ сервер решения полиномов (находит действительные корни полиномов методом Штурма). На сайте документация по API, но скажу прямо VPS слабенький и 200 000 полиномов. . .
Расчёт переходных процессов в цепи постоянного тока
igorrr37 16.01.2026
/ * Дана цепь постоянного тока с R, L, C, k(ключ), U, E, J. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа, решает её и находит переходные токи и напряжения на элементах схемы. . . .
Восстановить юзерскрипты Greasemonkey из бэкапа браузера
damix 15.01.2026
Если восстановить из бэкапа профиль Firefox после переустановки винды, то список юзерскриптов в Greasemonkey будет пустым. Но восстановить их можно так. Для этого понадобится консольная утилита. . .
Сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru