Поиск:

Ответ в темуСоздание новой темы Создание опроса
> UTF8, не читается файл 
:(
    Опции темы
livo
Дата 26.4.2012, 18:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Доброго времени суток.
Задача такова: есть файл, сохраненный в кодировке UTF 8, который необходимо загрузить и, расшифровав, отобразить в TRichEdit. Использовал модифицированные примеры из этого форума, но чего-то не пашет. Коротко опишу код:
Есть две функции одна - wstostr - расшифровывает переданную ей строку; вторая - LoadUTF8 - считывает данные с файла. Все эти радости запускаются кнопкой в процедуре sBitBtn1Click. Два файла, которые я пытался расшифровать находятся в прилагаемом архиве. Они сохранялись программой Notepad++ в кодировках UTF8 и UTF8 without BOM (не знаю в чем между ними разница).
И еще, у меня 6-й билдер.
Код

//---------------------------------------------------------------------------
String wstostr(const std::wstring &ws)
{
    std::string str;
    int n = WideCharToMultiByte(CP_ACP, 0, ws.c_str(), ws.size()+1, NULL, 0, 0, NULL);
    if(n)
    {
        str.resize(n-1);
        if(WideCharToMultiByte(CP_ACP, 0, ws.c_str(), ws.size()+1, &str[0], n, 0, NULL) == 0)
            str.clear();
    }
    return str.data();
}
//---------------------------------------------------------------------------
String LoadUTF8(String fn)
{
 TFileStream *fs=0;
 std::wstring ws;
 String out;
 try
 {
   fs=new TFileStream(fn,fmOpenRead|fmShareDenyWrite);
   ws.resize(fs->Size);
   fs->ReadBuffer(&ws[0],fs->Size);
   out=wstostr(ws);
   delete fs;
 }
 catch(...)
 {
   if(fs)delete fs;
   return "";
 }
 return out;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::sBitBtn1Click(TObject *Sender)
{ 
 if(RadioButton1->Checked)redt->Text=LoadUTF8("1.txt");
 if(RadioButton2->Checked)redt->Text=LoadUTF8("2.txt");
}
//---------------------------------------------------------------------------


Присоединённый файл ( Кол-во скачиваний: 1 )
Присоединённый файл  utf8.rar 0,67 Kb
PM MAIL   Вверх
Alexeis
Дата 26.4.2012, 18:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 26
Всего: 459



  UTF8 это не WideChar строка, а MultiByte . Помещать ее в wstring неправильно. Можно использовать string.
Соответственно вызываем MultiByteToWideChar и получаем строку в формате UTF16 .Дальше UTF16 в ANSI


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
livo
Дата 27.4.2012, 14:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Ну, понял. Вот как-то так:
Код

String encoding(const std::string &src, const unsigned &cp_src,const unsigned &cp_dest)
{//вспомогательная функция
    std::wstring ws;
    std::string out;
    int n = MultiByteToWideChar(cp_src, 0, src.c_str(), src.size()+1, NULL, 0);
    if(n)
    {
        ws.resize(n-1);
        if(MultiByteToWideChar(cp_src, 0, src.c_str(), src.size()+1, &ws[0], n) != 0)
        {
          n = WideCharToMultiByte(cp_dest, 0, ws.c_str(), ws.size()+1, NULL, 0, NULL,0);
          if(n)
          {
            out.resize(n-1);
            if(WideCharToMultiByte(cp_dest, 0, ws.c_str(), ws.size()+1, &out[0], n, NULL,0) == 0)
              out.clear();
          }
        }
    }
    return out.data();
}
//---------------------------------------------------------------------------
String LoadUTF8(String fn)
{//загрузка из файла
 TFileStream *fs=0;
 std::string buff;
 String out;
 try
 {
   fs=new TFileStream(fn,fmOpenRead|fmShareDenyWrite);
   buff.resize(fs->Size);
   fs->ReadBuffer(&buff[0],fs->Size);
   out=encoding(buff,CP_UTF8,CP_ACP);
 }
 catch(...)
 {}
 if(fs)delete fs;
 return out;
}
//---------------------------------------------------------------------------
void SaveUTF8(String fn,String src)
{//сохранение в файл
 TFileStream *fs=0;
 std::string buff(src.c_str(),src.Length());
 buff=encoding(buff,CP_ACP,CP_UTF8).c_str();
 try
 {
   fs=new TFileStream(fn,fmCreate|fmShareDenyNone);
   fs->WriteBuffer(buff.data(),buff.size());
 }
 catch(...)
 {}
 if(fs)delete fs;
}

Работал с теми файлами, что описывал выше. Результат:
  • Кодировка UTF8 without BOM - загрузка и сохранение работают.
  • Кодировка UTF8 - загрузка работает, но в начале отображается знак вопроса; сохранение вследствие этого производится некорректно.
Почему?
PM MAIL   Вверх
Alexeis
Дата 27.4.2012, 14:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 26
Всего: 459



Цитата(livo @  27.4.2012,  15:43 Найти цитируемый пост)
Кодировка UTF8 - загрузка работает, но в начале отображается знак вопроса; сохранение вследствие этого производится некорректно.

  Очевидно что знак вопроса это BOM. Его нужно пропускать при чтении. При записи заносить первым. 
  


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
artsb
Дата 28.4.2012, 20:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

Репутация: 39
Всего: 64



Цитата(livo @  26.4.2012,  18:04 Найти цитируемый пост)
в кодировках UTF8 и UTF8 without BOM (не знаю в чем между ними разница).

BOM - это Byte order mark, т.е. несколько байт, которые записываются перед данными и указывают на то, какие данные идут дальше. BOM очень часто используется в структурированных файлах.


--------------------
Чем отличается умный человек от мудрого?
Умный - выпутается из любой ситуации.
Мудрый - просто в неё не попадёт.
PM MAIL   Вверх
kovamoka
Дата 20.5.2012, 03:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Цитата(artsb @ 28.4.2012,  20:47)
Цитата(livo @  26.4.2012,  18:04 Найти цитируемый пост)
в кодировках UTF8 и UTF8 without BOM (не знаю в чем между ними разница).

BOM - это Byte order mark, т.е. несколько байт, которые записываются перед данными и указывают на то, какие данные идут дальше. BOM очень часто используется в структурированных файлах.

Я не думаю что оно использует структурирование. Это на яве проде кодеровку сменить можно.
PM MAIL WWW   Вверх
artsb
Дата 20.5.2012, 21:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

Репутация: 39
Всего: 64



Цитата(kovamoka @  20.5.2012,  03:59 Найти цитируемый пост)

Я не думаю что оно использует структурирование. Это на яве проде кодеровку сменить можно. 

Я имел ввиду не именно кодировку. BOM используется для обозначения типа шапки например. Чтобы можно было однозначно её определить. Взять тот же ZIP: у каждой шапки есть свой BOM.


--------------------
Чем отличается умный человек от мудрого?
Умный - выпутается из любой ситуации.
Мудрый - просто в неё не попадёт.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++ Builder"
Rrader

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

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

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

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


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

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


 




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


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

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