Поиск:

Ответ в темуСоздание новой темы Создание опроса
> [BCB2009] Сохранение структур с Unicode в файл 
:(
    Опции темы
mr.Anderson
Дата 16.5.2009, 20:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


iOS Lead Developer
****


Профиль
Группа: Участник Клуба
Сообщений: 3374
Регистрация: 20.12.2004
Где: далеко

Репутация: 3
Всего: 128



Возникла задача сохранить структуру, содержащую строки, в бинарный файл. Оттуда потом в бинарном же режиме все это удовольствие нужно считать. Строки хоть char *, хоть UnicodeString - не суть, лишь бы работало. По умолчанию в Билдере, насколько я знаю, char тоже юникодный. В интернете нашел только сохранение через data(), но не знаю, как это использовать при записи и чтении структуры.

Структура имеет следующий вид:
Код

typedef UnicodeString UString;

typedef struct {
    UString word;
    UString hint;
    bool placed;
    int x;
    int y;
    bool h;
} TWord;

Процедура вывода этой структуры:
Код

void printStruct(TWord *W)
{
    printf("\nword: %s\nhint: %s\nplaced: %d\nx: %d\ny: %d\nh: %d\n", W->word, W->hint, W->placed, W->x, W->y, W->h);
}

И сама главная процедура, пишущая и читающая из файла в бинарном режиме.
Код

void main()
{
    TWord *W = new TWord();
    W->word = "MyWord";
    W->hint = "NoHint";

    FILE *f;
    f = fopen("test.txt", "wb");
    fwrite(&W, sizeof(TWord), 1, f);
    fclose(f);

    delete W;
    W = new TWord();
    f = fopen("test.txt", "rb");
    fread(&W, sizeof(TWord), 1, f);
    fclose(f);

    printStruct(W);
    delete W;
    W = NULL;
    getch();
}

В итоге после чтения из файла обе строки в переменной W имеют NULL как сами по себе, так и в своем data(). Как быть?

Это сообщение отредактировал(а) mr.Anderson - 16.5.2009, 20:31


--------------------
user posted image

user posted image
PM MAIL ICQ Skype   Вверх
A5uKa
Дата 17.5.2009, 10:31 (ссылка)    | (голосов:3) Загрузка ... Загрузка ... Быстрая цитата Цитата


TЋ♥s F1rȜ iƧ BurȠiƞg
***


Профиль
Группа: Awaiting Authorisation
Сообщений: 1928
Регистрация: 30.8.2008

Репутация: 2
Всего: 16



Может в fopen с w ?
PM   Вверх
mr.Anderson
Дата 17.5.2009, 15:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


iOS Lead Developer
****


Профиль
Группа: Участник Клуба
Сообщений: 3374
Регистрация: 20.12.2004
Где: далеко

Репутация: 3
Всего: 128



A5uKa, думаем, что говорим. Если не знаете, лучше ничего не писать.

Ну что, никто не сталкивался с этой проблемой, что ли?


--------------------
user posted image

user posted image
PM MAIL ICQ Skype   Вверх
dumb
Дата 17.5.2009, 15:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


sceloglauxalbifacies
****


Профиль
Группа: Экс. модератор
Сообщений: 2929
Регистрация: 16.6.2006

Репутация: 32
Всего: 158



mr.Anderson, UString - это не POD-тип, поэтому либо для него нужно делать специальную обработку, либо вместо UString в структуре делать char[].
PM MAIL   Вверх
THandle
Дата 17.5.2009, 15:43 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Хранитель Клуба
Group Icon
Награды: 1



Профиль
Группа: Админ
Сообщений: 3639
Регистрация: 31.7.2007
Где: Moscow, Dubai

Репутация: 25
Всего: 372



mr.Anderson, вообще строка это по идее указатель и его просто так не запишешь. Надо сначала длину, а потом уже строку. Распространенная ошибка)

Вот вариант через TWriter.

Код


#include <memory>

typedef struct {
    UnicodeString word;
    UnicodeString hint;
    bool placed;
    int x;
    int y;
    bool h;
} TWord;


void WriteStruct(UnicodeString FileName, TWord* Word)
{
    std::auto_ptr<TFileStream> fs(new TFileStream(FileName, fmCreate));
    std::auto_ptr<TWriter> Writer(new TWriter(fs.get(), 16));
    Writer->WriteListBegin();
    Writer->WriteString(Word->word);
    Writer->WriteString(Word->hint);
    Writer->WriteBoolean(Word->placed);
    Writer->WriteInteger(Word->x);
    Writer->WriteInteger(Word->y);
    Writer->WriteBoolean(Word->h);
    Writer->WriteListEnd();
}
//---------------------------------------------------------------------------
__fastcall TForm2::TForm2(TComponent* Owner)
    : TForm(Owner)
{
    TWord* Word = new TWord();
    Word->hint = "THandle";
    Word->word = "Hello!!!";
    WriteStruct("C:\\testafile", Word);
    delete Word;
}
//---------------------------------------------------------------------------
void __fastcall TForm2::Button2Click(TObject *Sender)
{
    TWord* Word = new TWord();
    std::auto_ptr<TFileStream> fs(new TFileStream("C:\\testafile", fmOpenRead));
    std::auto_ptr<TReader> Reader(new TReader(fs.get(), 16));
    Reader->ReadListBegin();
    Word->word = Reader->ReadString();
    Word->hint = Reader->ReadString();
    Word->placed = Reader->ReadBoolean();
    Word->x = Reader->ReadInteger();
    Word->y = Reader->ReadInteger();
    Word->h = Reader->ReadBoolean();
    Reader->ReadListEnd();
    ShowMessage(Word->word);
    ShowMessage(Word->hint);
}

PM   Вверх
mr.Anderson
Дата 17.5.2009, 15:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


iOS Lead Developer
****


Профиль
Группа: Участник Клуба
Сообщений: 3374
Регистрация: 20.12.2004
Где: далеко

Репутация: 3
Всего: 128



THandle, ага)) Только у меня еще заработало вот так:
Код

void main()
{
    TWord *W = new TWord();
    W->word = "MyWord";
    W->hint = "NoHint";
    FILE *f;
    f = fopen("test.txt", "wb");
    fwrite(W, sizeof(TWord), 1, f); // <-- а всего лишь зря поставил & перед W...
    fclose(f);
    delete W;
    W = new TWord();
    f = fopen("test.txt", "rb");
    fread(W, sizeof(TWord), 1, f);
    fclose(f);
    printStruct(W);
    delete W;
    W = NULL;
    getch();
}

И еще надо было подправить вывод, printf("%s") не срабатывает. Я пока ищу модификатор для вывода юникодных строк в BCB2009, но пока сделал топорно (зато работает)
Код

void printUnicode(UString s)
{
    for (int i=1; i<=s.Length(); i++)
        printf("%c", s[i]);
}

Ну и в выводе, соответственно:
Код

void printStruct(TWord *W)
{
    printUnicode(W->word);
    printf("\n");
    printUnicode(W->hint);
    printf("\nplaced: %d\nx: %d\ny: %d\nh: %d\n", W->placed, W->x, W->y, W->h);
}



--------------------
user posted image

user posted image
PM MAIL ICQ Skype   Вверх
Alca
Дата 17.5.2009, 22:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3993
Регистрация: 14.6.2006

Репутация: 25
Всего: 50



Для юникода:
Код

    TWord *W = new TWord();
    W->word = L"MyWord";
    W->hint = L"NoHint";



--------------------
PM WWW ICQ Skype Jabber   Вверх
mrbrooks
Дата 18.5.2009, 08:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


трололомен
****


Профиль
Группа: Завсегдатай
Сообщений: 4259
Регистрация: 4.10.2006
Где: Дол Гулдур

Репутация: 167
Всего: 306



 smile Ребята - вы что на Дельфи пишете?  smile Обычно (обычно) под консоль VCL - классы не юзают, ибо есть и так большое количество прекрасных библиотек. Взять тот же STL. Строки там ничуть не хуже.  smile Дело ваше конечно.

Цитата(mr.Anderson @  17.5.2009,  15:48 Найти цитируемый пост)
THandle, ага)) Только у меня еще заработало вот так:

выглядит зловеще  smile 

Цитата(mr.Anderson @  17.5.2009,  15:48 Найти цитируемый пост)
И еще надо было подправить вывод, printf("%s") не срабатывает. Я пока ищу модификатор для вывода юникодных строк в BCB2009, но пока сделал топорно (зато работает)


Интересный подход  smile 
Однако замечу - все несколько проще. Стандартная библиотека включает в себя функции, как для анси-строк, так и для юникод-строк. см. здесь

зы. THandle, камрад вроде как не брезгуешь std::auto_ptr, отчего по классике память выделяешь  smile? Конечно не критично - просто глаз режет.
PM MAIL   Вверх
dumb
Дата 18.5.2009, 12:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


sceloglauxalbifacies
****


Профиль
Группа: Экс. модератор
Сообщений: 2929
Регистрация: 16.6.2006

Репутация: 32
Всего: 158



Цитата(mr.Anderson @  17.5.2009,  15:48 Найти цитируемый пост)
Только у меня еще заработало вот так

вот так заработало только потому, что блоки записи и чтения идут друг за другом и расположение строк в памяти не меняется. не в тесте такое работать не будет.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++ Builder"
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по С++ Builder обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Настоятельно рекомендуем заглянуть в DRKB (Delphi Russian Knowledge Base) - крупнейший в рунете сборник материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C++ Builder | Следующая тема »


 




[ Время генерации скрипта: 0.0760 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.