|
Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Программирование и базы данных » C++ Builder || Файловый ввод/вывод |
|
C++ Builder || Файловый ввод/вывод
|
Пользователь Сообщения: 86 |
Профиль | Отправить PM | Цитировать Есть класс:
class dep{ AnsiString name; int Sum; //... AnsiString person; public: AnsiString get_name(); int get_sum(); //... } //далее следуют описания функций-членов //... //запись в файл данных из экземпляров класса dep //... // считываем данные из файла dep temp_dep; fstream file("data.dat", ios::binary | ios::in); file.read((char*)&temp_dep, sizeof(dep)); Form1->StringGrid1->Cells[1][1] = temp_dep.get_name{}; Form1->StringGrid1->Cells[1][1] = AnsiString(temp_dep.get_sum{}); //...{ Спасибо за помощь. |
|
Отправлено: 21:12, 02-11-2006 |
редкий гость Сообщения: 1696
|
Профиль | Сайт | Отправить PM | Цитировать Sir Z
Предлагаю вам ознакомиться с тем как представляются строки в памяти. А представляются они как правило указателем на первый символ строки и длиной строки. т.е. условно говоря строка представляет из себя Когда вы записываете свою структуру в файл (скорее всего делая fstream::write) вы записываете только 8 байт, а не саму строку. В любом случае придётся делать некий метод сериализации/десериализации. Примерно так: class dep{ AnsiString name; int Sum; //... AnsiString person; public: AnsiString get_name(); int get_sum(); //... // конструктор из файла // можно и простым методом оформить dep(std::fstream &s) { s.read(&Sum, sizeof(sum)); // и так для всех POD-данных size_t len; s.read(&len, sizeof(len)); name.SetLength(len); s.read(name.data(), len); } // метод для сохранения в файл void serialize(std::fstream &s) { s.write(&Sum, sizeof(sum)); // ... size_t len = name.Length(); s.write(&len, sizeof(len)); s.write(name.data(), len); } } |
------- Последний раз редактировалось ivank, 04-11-2006 в 17:19. Отправлено: 23:15, 02-11-2006 | #2 |
Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети. Если же вы забыли свой пароль на форуме, то воспользуйтесь данной ссылкой для восстановления пароля. |
Пользователь Сообщения: 86
|
Профиль | Отправить PM | Цитировать Предложенный Вами метод вообще исключает логическую связность хранимых данных, для чего был создан класс dep. Если идти таким путем, гораздо легче записывать подряд название, сумму, имя человека, название, сумму, имя человека и т.д. Вряд ли это оптимальный вариант в данной ситуации.
Подчеркну, что данные предпочтительно хранить именно в AnsiString вследствие внутреннего строения большинства компонентов vcl. Неужели крутые программеры, записывая данные из класса в файл, вручную переносят значения ВСЕХ переменных? |
Отправлено: 01:08, 04-11-2006 | #3 |
Старый параноик Сообщения: 2423
|
Профиль | Отправить PM | Цитировать Sir Z
Почитайте чего-нибудь про сериализацию классов. В гугле есть. >> Неужели крутые программеры, записывая данные из класса в файл, вручную переносят значения ВСЕХ переменных? Ох, не могу не похвалиться... Написал (уже полностью) библиотеку на QT, которая любой класс обучает самосериализации. Типа берёшь класс, добавляешь интерфейс спецмакросом, в спецметоде описываешь регистрацию переменных для выброса-вброса в XML - и всё. В любой момент ррраз - и класс пишет или читает себя и всех вложенных детей (в том числе и других таких же классов) в файл :-) Поддерживаются даже массивы. Дикая смесь шаблонов, макросов и наследований... :-) Мой лучший (пока) в жизни системный продуктик... |
Отправлено: 01:18, 04-11-2006 | #4 |
редкий гость Сообщения: 1696
|
Профиль | Сайт | Отправить PM | Цитировать Sir Z
Цитата:
Сейчас сериализацию модно автоматически (т.е. без написания своего кода) с помощью reflection делать. Но это в .NET/Java + скриптовых языках. На C++ не проканает. На C++ можно действительно можно пользоваться макросами для автонаписания подобного кода. Или boost::serialization, который вполне вероятно войдёт в следующий стандарт C++. hasherfrog А я подобную штуку (макросы для автомериализации) ещё лет 5 назад писал, в качестве proof of concept. Правда в голые файлы сохранял всё. Не любил XML, да и не люблю до сих пор. К сожалению, моя первая дом. страница закрылась раньше, чем её проиндексировал webarchive.org Все свои поделки я выкладывал именно там. А теперь ведь и взять больше неоткуда того чуда, дабы над ним посмеяться |
||
------- Отправлено: 02:21, 04-11-2006 | #5 |
Ветеран Сообщения: 1180
|
Профиль | Отправить PM | Цитировать Sir Z, честно говоря, я не совсем понял, чего вы хотите добиться. Из того что вами написано, могу только поддержать ответивших вам форумчан. Давайте поясню:
class dep{ AnsiString name; int Sum; // класс, который содержит имя, сумму и проч. в КАЖДОМ экзеспляре // причём тут связность или несвязность? public: // здесь ivank добавил методы, которые безопасно выполняют то, // что вы довольно жестоко делаете в разделе "считываем данные из файла" } // считываем данные из файла dep temp_dep; fstream file("data.dat", ios::binary | ios::in); // БЕЗОПАСНОСТЬ ТИПОВ ДАННЫХ - это то, из-за чего отказались от C и придумали C++ file.read((char*)&temp_dep, sizeof(dep)); // вы сейчас память покалечили, это и хотел сказать ivank // кроме того, iostream - для работы с данными в текстовом виде, а не дампа памяти Form1->StringGrid1->Cells[1][1] = temp_dep.get_name{}; // зачем это было делать? Form1->StringGrid1->Cells[1][1] = AnsiString(temp_dep.get_sum{}); // всё равно поверх записали что-то //...{ |
Отправлено: 11:04, 04-11-2006 | #6 |
Пользователь Сообщения: 86
|
Профиль | Отправить PM | Цитировать pva:
Давайте по порядку. 1. Когда я говорил о связности, я говорил о том, что гораздо удобнее читать весь объект сразу, а не его члены по отдельности. И так же записывать. 2. Цитата:
Цитата:
Цитата:
Цитата:
ЦЕЛЬ: есть класс, представляющий, к примеру, человека. Человек должно быть несколько(разных) и этот список надо хранить в файле. Данные хотелось бы защитить от чтения вне программы, поэтому читаю и пишу бинарно. Кстати, где достать классы шифрования данных? |
||||
Отправлено: 15:26, 04-11-2006 | #7 |
редкий гость Сообщения: 1696
|
Профиль | Сайт | Отправить PM | Цитировать Sir Z
Цитата:
Вы знаете что такое указатель? А C-строки? Давайте ещё попробую объяснить всё ещё более на пальцах, чем до этого. C-строка - это указатель на первый элемент строки. Строка это просто последовательность символов (char), заканчивающаяся символом '\0'. char *str = (char*)malloc(100); //выделили 100 байт памяти // предположим, что str указывает на ячейку 0xdecafbad strcpy(str, "some string"); //записали в строку "some string" по адресу 0xdecafbad outfile.write(&str, sizeof(str)); // записываем четыере байта - только указатель free(str); // освобождаем памяти // Таким образом в файле - 4 байта - 0xdecafbad, а не требумая нам строка // .... infile.read(&str, sizeof(str)); // считали 4 байта // Теперь str=0xdecafbad. но память по этому адресу ещё не выделена // и тем более ничем не инициализирована // Проще говоря str указывает на мусор, со всеми вытекающими P.S. записывать любые дынные сложнее, чем простые встроенные типы (int, char, double итп) банальным дампом памяти в двоичный файл нельзя. Да и то, даже с простыми типами будут появляться проблемы с переносом на различные архитектуры, ибо размер int может быть как 2 байта, так и 4 и 8. И порядок следования байтов может быть на разных платформах различный. Текстовые форматы надёжней. Цитата:
Цитата:
|
|||
------- Отправлено: 17:41, 04-11-2006 | #8 |
Участник сейчас на форуме | Участник вне форума | Автор темы | Сообщение прикреплено |
| |||||
Название темы | Автор | Информация о форуме | Ответов | Последнее сообщение | |
C/C++ - [решено] Файловый ввод | Lisiy_egik | Программирование и базы данных | 1 | 20-01-2010 05:40 | |
Debian/Ubuntu - Файловый сервер | Joni | Общий по Linux | 4 | 02-12-2008 14:29 | |
Основы C++ | Файловый ввод | Skrip | Программирование и базы данных | 12 | 05-08-2005 18:52 | |
файловый менджеры | rblack | Программное обеспечение Windows | 7 | 10-11-2004 15:17 | |
Файловый ввод-вывод в ring0 | wano | Программирование и базы данных | 13 | 12-11-2002 18:21 |
|