Поиск:

Ответ в темуСоздание новой темы Создание опроса
> String в файл 
V
    Опции темы
FallenAngel
Дата 23.7.2009, 16:46 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











Доброго времени суток!

Есть строковый массив:
Код

String str[64];

длина строк варьируется.
Как его можно записать в бинарный файл?
  Вверх
Artemon
Дата 23.7.2009, 17:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


а ты мне нравишься
***


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

Репутация: 7
Всего: 20



Код

FILE* f = fopen("data.bin", "wb"); /// Именно бинарный режим записи

for( int k = 0; k < 64; k++ )
   fwrite( str[k].c_str(), str[k].Length(), 1, f );

fclose(f);




--------------------
Контроль топлива на топливозаправщиках, мониторинг автотранспорта, расчет зарплаты водителей www.rscat.ru
PM MAIL   Вверх
FallenAngel
Дата 23.7.2009, 17:28 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











таким способом записываюся не все символы из каждой строки, а лишь часть их.
например: если строка была длиной 7 символов, записались только 4.
Из 17-ти записались 9.

Это сообщение отредактировал(а) FallenAngel - 23.7.2009, 17:41
  Вверх
Artemon
Дата 23.7.2009, 18:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


а ты мне нравишься
***


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

Репутация: 7
Всего: 20



Вообще изначально неправильно записывать строки в бинарный файл, вы их потом от туда никаким образом считать не сможете.

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

Думаю вам больше подойдет запись в текстовом режиме ("wt" вместо "wb").
Если всетаки по какой-то причине вам нужно именно бинарный режим, то вам придется еще перед каждой стройко записывать ее размер, иначе у вас не получится потом их считать.


--------------------
Контроль топлива на топливозаправщиках, мониторинг автотранспорта, расчет зарплаты водителей www.rscat.ru
PM MAIL   Вверх
FallenAngel
Дата 23.7.2009, 19:08 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











Цитата(Artemon @  23.7.2009,  18:52 Найти цитируемый пост)
Думаю вам больше подойдет запись в текстовом режиме ("wt" вместо "wb").

А в чём разница? Запись производится-то одними и теми же функциями.
  Вверх
Artemon
Дата 23.7.2009, 19:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


а ты мне нравишься
***


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

Репутация: 7
Всего: 20



Если вы собираетесь в файл писать информацию, которую затем будете редактировать через текстовый редактор, то следует писать в текстовом режиме.

Если какие-то служебные данные (структуры например), то лучше в бинарном режиме.


--------------------
Контроль топлива на топливозаправщиках, мониторинг автотранспорта, расчет зарплаты водителей www.rscat.ru
PM MAIL   Вверх
shklowsky
Дата 23.7.2009, 19:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

Репутация: 5
Всего: 6



Код


TStingList *sl=new TStringList;
try
   {
   for(int i=0;i<64;++i)   sl->Add(str[i]);
   sl->SaveToFile("myFile.bin");
   }
__finally
   {
   delete sl;
   }



запишет как текст конечно.
а писать строки как данные- смысл...
потом их не разлепишь.
PM MAIL   Вверх
FallenAngel
Дата 23.7.2009, 19:48 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











Вообще в массив пишутся пути к некоторым файлам, и я затем всё это записываю в бинарник наряду с другими данными.

Запись в файл произвожу таким образом
Код

 for( int k=0; k<64; k++ )
    {
     int len=str[k].Length();
     fwrite( &len, sizeof(int), 1, stream );// stream - файловый поток
     fwrite( str[k].c_str(), len, 1, stream );
    }


но при считывании
Код

 for( int k=0; k<64; k++ )
    {
     int len=0;
     fread( &len, sizeof(int), 1, stream );
     fread( &str[k] , len, 1, stream );
    }
 

у меня в массив попадают непонятные иероглифы... B при этом в массиве как-то криво выделяется память
user posted image
это то, что получается после первого прохода по циклу.
  Вверх
Artemon
Дата 23.7.2009, 20:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


а ты мне нравишься
***


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

Репутация: 7
Всего: 20



Нельзя в тип String вот так просто считать данные из файла.

Нужно примерно так:

 for( int k=0; k<64; k++ )
    {
     int len=0;
     fread( &len, sizeof(int), 1, stream );
    
     char* Path = new char[ len + 1 ];
    
     fread( Path , len, 1, stream );

     Path[len] = '\0';

     String S = (AnsiString)Path; /// Аот на этом месте мы получим строку типа AnsiString

     delete [] Path;
     }

Это сообщение отредактировал(а) Artemon - 23.7.2009, 20:03


--------------------
Контроль топлива на топливозаправщиках, мониторинг автотранспорта, расчет зарплаты водителей www.rscat.ru
PM MAIL   Вверх
shklowsky
Дата 23.7.2009, 20:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

Репутация: 5
Всего: 6



Цитата(FallenAngel @  23.7.2009,  19:48 Найти цитируемый пост)
fread( &str[k] , len, 1, stream );

если str- это String то так неправильно.
Код

     int len=0;
     fread( &len, sizeof(int), 1, stream );
     str[k].SetLenght(len);
     fread( str[k].data() , len, 1, stream );


PM MAIL   Вверх
FallenAngel
Дата 23.7.2009, 20:22 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











При такой записи:
Цитата(FallenAngel @  23.7.2009,  19:48 Найти цитируемый пост)
fwrite( str[k].c_str(), len, 1, stream );

он после каждого символа вставляет "\0"

Artemon, может тогда проще всё перегнать в char'овский массив и его уже записывать и считывать?

Цитата(shklowsky @  23.7.2009,  20:02 Найти цитируемый пост)
 fread( str[k].data() , len, 1, stream );

ругается на невозможность преобразовать "*void" в "const* void"


  Вверх
shklowsky
Дата 23.7.2009, 20:28 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

Репутация: 5
Всего: 6



Цитата(FallenAngel @  23.7.2009,  20:22 Найти цитируемый пост)
ругается на невозможность преобразовать "*void" в "const* void"


а мы попросим:
Код

 fread( (void*)str[k].data() , len, 1, stream );
//  или
 fread(const_cast<void*> (str[k].data() ), len, 1, stream );


PM MAIL   Вверх
Artemon
Дата 23.7.2009, 20:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


а ты мне нравишься
***


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

Репутация: 7
Всего: 20



Если вы в дальнейшем постоянно работате с массивом строк, то лучше всего его так и оставить типа String.
А если к примеру вы используете это массив единожды, чтобы загрущить из него данные в дерево, то на мой взгляд лучше ввобще убрать, а дерево формировать прямо в цикле, в котором происходит загрузка из файла.

И еще, я думаю стоит в начале файла записать число int, которое будет содерджать общее число пар (размер/строка) в файле. Первым делом считывать его и организовывать цикл от 0 до этого числа, а не задавать его константой.


--------------------
Контроль топлива на топливозаправщиках, мониторинг автотранспорта, расчет зарплаты водителей www.rscat.ru
PM MAIL   Вверх
FallenAngel
Дата 23.7.2009, 20:42 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











Спасибо за помощь, вопрос решён!smile
  Вверх
shklowsky
Дата 23.7.2009, 20:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

Репутация: 5
Всего: 6



Цитата(FallenAngel @  23.7.2009,  20:22 Найти цитируемый пост)
он после каждого символа вставляет "\0"


не должен.
 метод AnsiString::Length() возвращает длину строки без завершающего нуля.
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++ Builder"
Rrader

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

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

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

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


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

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


 




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


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

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