Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 19.01.2011, 13:38   #1
Кипящий чайник
Форумчанин
 
Регистрация: 17.12.2009
Сообщений: 101
По умолчанию Чтение/запись структуры

Всё на Си, потому что графическая библиотека тоже сишная. Суть в том, что не получается корректно считать структуру из файла.
Система Ubuntu Linux, компилируется из командной строки посредством gcc.

Код:
#include <stdio.h>
#include <stdlib.h>
#include <SDL/SDL.h>

typedef struct p{
     char* name;
     int age;
} t_probe;

int main(){
     t_probe one;
     one.name = "Иван";
     one.age = 26;

     /*Записываем в файл*/
     FILE* fd = fopen("data", "wb");
     fwrite(&one, sizeof(t_probe), 1, fd);
     fclose(fd);

     /*Считываем из файла*/
     t_probe two;
     fd = fopen("data", "rb");
     fread(&two, sizeof(t_probe), 1, fd);
     fclose(fd);

     printf("%s %d\n", two.name, two.age);
     return 0;
}
Если эти операции выполняются друг за другом в одной программе, то в two всё прекрасно считывается. Однако, если я оставлю только процедуру считывания (файл уже существует, и в нём есть информация), то символьная переменная не считывается. Переменная age читается прекрасно, да и вообще все числовые переменные. А вот строчные - хоть убей, но никак. Вместо них выводится пустое место. Как же заставить их считываться?
Кипящий чайник вне форума Ответить с цитированием
Старый 19.01.2011, 17:46   #2
Кипящий чайник
Форумчанин
 
Регистрация: 17.12.2009
Сообщений: 101
По умолчанию

Неужели нет идей? Если это оттого, что здесь полно тем с похожими названиями, то я не нашёл ни в одной из них ответа на свой вопрос.
Кипящий чайник вне форума Ответить с цитированием
Старый 19.01.2011, 18:10   #3
Hacker19_90
Delphi Warrior
Старожил
 
Аватар для Hacker19_90
 
Регистрация: 15.08.2008
Сообщений: 2,502
По умолчанию

Точно не скажу! но у самого часто бывали проблемы со считыванием структур со строчными полями! Тут дело в том (наверно) что у структуры одно из полей char* name;! Попробуйте задать конкретный размер char name[10]; и прогоните ещё раз!
Mess with the best, die like the rest. (с) Hackers
Лабораторные, курсовые на Delphi\Pascal\C++
ya.flex-freelance@yandex.ru Icq - 636-954-303
Hacker19_90 вне форума Ответить с цитированием
Старый 19.01.2011, 18:21   #4
Кипящий чайник
Форумчанин
 
Регистрация: 17.12.2009
Сообщений: 101
По умолчанию

Пробовал уже... Бесполезняк.
Кипящий чайник вне форума Ответить с цитированием
Старый 19.01.2011, 18:29   #5
An1ka
C++,DirectX/OpenGL
Форумчанин
 
Регистрация: 09.01.2011
Сообщений: 422
По умолчанию

У тебя в структуре указатель. А ты берешь sizeof(t_probe) и получаешь размер указателя, а не размер строки !
Да и вообще ты в файл пишешь адрес указателя, а не строку

Последний раз редактировалось An1ka; 19.01.2011 в 18:59.
An1ka вне форума Ответить с цитированием
Старый 19.01.2011, 18:36   #6
Кипящий чайник
Форумчанин
 
Регистрация: 17.12.2009
Сообщений: 101
По умолчанию

Что тогда посоветуешь?
Кипящий чайник вне форума Ответить с цитированием
Старый 19.01.2011, 18:40   #7
Dayman
Форумчанин
 
Аватар для Dayman
 
Регистрация: 12.01.2011
Сообщений: 186
По умолчанию

Символьные поля неопределенного размера так не пишутся, и уж тем более так не читаются. Вы пишите и читаете адрес указателя.
Код:
#include <string.h> // Для strlen
one.name = "Иван\0"; // Честно скажу, что не помню дописывается ли \0 автоматически при такой инициализации, но пусть будет
size_t strsize=strlen(one.name)+1; // Считаем длину строки с \0
fwrite(&strsize, sizeof(size_t), 1, fd); // Пишем длину строки с \0
fwrite(one.name, strsize, 1, fd); // Пишем строку + \0
fwrite(&one.age, 4, 1, fd);
Чтение:
Код:
fread(&strsize, sizeof(size_t), 1, fd); // Читаем длину строки с \0
two.name=new char[strsize]; // Выделяем память
// Либо two.name=malloc(strsize); // Если чистый C
fread(two.name, strsize, 1, fd); // Читаем строку + \0
fread(&two.age, 4, 1, fd);
Lingua c++ non penis caninus est.
Dayman вне форума Ответить с цитированием
Старый 19.01.2011, 19:27   #8
An1ka
C++,DirectX/OpenGL
Форумчанин
 
Регистрация: 09.01.2011
Сообщений: 422
По умолчанию

Самое простое - сделать фиксированную длину строки.
Код:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <SDL/SDL.h>

typedef struct p{
	 char name[10];
	 int age;
         // Конструктор обнуляет строку.
	 p ( )
	 {
		memset ( name, 0, 10);
	 }
} t_probe;

int main(){
	 t_probe one;
	 strcpy(one.name, "Иван");
	 one.age = 26;
	 /*Записываем в файл*/
	 FILE* fd = fopen("data", "wb");
	 fwrite(&one, 1, sizeof(t_probe), fd);
	 fclose(fd);

	 /*Считываем из файла*/
	 t_probe two;
	 two.age = 0;
	 fd = fopen("data", "rb");
	 fread(&two, 1, sizeof(t_probe), fd);
	 fclose(fd);

	 printf("%s %d\n", two.name, two.age);
	 return 0;
}

Последний раз редактировалось An1ka; 19.01.2011 в 22:08.
An1ka вне форума Ответить с цитированием
Старый 19.01.2011, 20:48   #9
Кипящий чайник
Форумчанин
 
Регистрация: 17.12.2009
Сообщений: 101
По умолчанию

Dayman Я тоже так делаю, что же ещё остаётся? Но я хотел бы именно считывать одним махом, не отвлекаясь.

An1ka Несмотря на то, что в структурах Си нет конструкторов, ваш способ отлично работает! Спасибо большое!
Кипящий чайник вне форума Ответить с цитированием
Старый 19.01.2011, 20:56   #10
Dayman
Форумчанин
 
Аватар для Dayman
 
Регистрация: 12.01.2011
Сообщений: 186
По умолчанию

Цитата:
Сообщение от Кипящий чайник Посмотреть сообщение
Dayman Я тоже так делаю, что же ещё остаётся? Но я хотел бы именно считывать одним махом, не отвлекаясь.
Боюсь для строк переменной длины так не получится. Альтернативно, если у вас есть возможность изменять формат на ваше усмотрение, а структура достаточно большая, то строки переменной длины можно перенести в конец структуры и читать так:
Код:
fread(&struct, sizeof(struct)-sizeof(char*) * number_of_strings,1,file);
А затем дочитывать строки.
То есть сначала будут считаны данные структуры до строк переменной длины.
Lingua c++ non penis caninus est.
Dayman вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Чтение и запись структуры в бинарный файл Bed Alice Общие вопросы C/C++ 1 09.11.2010 21:17
Чтение структуры из файла atenon Общие вопросы C/C++ 11 22.10.2010 20:35
сохранение/чтение структуры с файла Vorname Общие вопросы C/C++ 4 10.11.2009 17:59
Запись структуры и чтение из файла [MI_nor] Общие вопросы C/C++ 6 08.04.2009 15:52
Чтение структуры файла SDK Помощь студентам 4 23.01.2008 19:30