Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Запись CString в файл, Проблема с кодировкой WideChar/MultiByte 
:(
    Опции темы
SAVe
Дата 11.12.2007, 12:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Я создал файл (в Notepad) и сохранил его в кодировке UTF-8 (это xml код). Файл открывается в броузере.Файл содержит русские и английские символы. Читаю файл таким кодом:
Код

CFile file;
    
    
    if(!file.Open(fileName,CFile::modeRead))
    {
        return;
    }
    // Размер файла в байтах. Он же последний индекс в строке mbBuffer
    int FileLen = (int)file.GetLength();
    int mbBuffLen = FileLen + 1;
    char* mbBuffer = new char[mbBuffLen];
    file.Read(mbBuffer,FileLen);
    file.Close();

    mbBuffer[FileLen] = 0;
    // Необходимый  размер буффера для Unicod строки. 
    // Функция вызванная с такими параметрами его вернёт
    int wcBuffLen = MultiByteToWideChar(CP_UTF8,0,mbBuffer,-1,NULL,0);
    wchar_t* wcBuffer = new wchar_t[wcBuffLen];
    // Преобразуем в Unicod
    MultiByteToWideChar(CP_UTF8,0,mbBuffer,-1,wcBuffer,wcBuffLen);
                // this->docIn это CString
    this->docIn = wcBuffer;
    delete[] mbBuffer;
    delete[] wcBuffer;


Всё отлично читается и преобразуется. Русские символы отображаются. Полученнная строка docIn обрабатывается программой и на выходе получается строка docOut (CString) которую нужно сохранить в файл. Русские символы в ней так же нормально отображены после обработки. 

Перед сохранением в файл пытаюсь конвертировать обратно

Код

               // В this->docOut символы отображены правильно
                LPCWSTR wcBuffer = (LPCWSTR)this->docOut.GetBuffer();                 
    int bufSize = WideCharToMultiByte(CP_UTF8,0,wcBuffer,-1,NULL,0,NULL,NULL);
    char* mbBuffer = new char[bufSize];
    WideCharToMultiByte(CP_UTF8,0,wcBuffer,-1,(LPSTR mbBuffer,bufSize,NULL,NULL);                
    this->docOut = mbBuffer;
    delete[]  mbBuffer;



Теперь пытаюсь записать полученную строку в файл (сохраняю в объект CArchive т.к. уменя SDI приложение)
Код

void AppDoc::Serialize(CArchive& ar)
{
    
    if (ar.IsStoring())
    {
        // TODO: add storing code here
                ar<<this->doc.docOut;
    }
    else
    {
        // TODO: add loading code here
    }
}


В результате в файле записана ерунда всякая. Пробовал разные кодировки подставлять - то же самое. Пробовал просто сохранить docOut без предварительно конвертации - латнские символы сохранились , русские нет (и файл не открывается в браузере по причине не верной кодировки).

Подскажите пожалуйста как решить прблему. Нужно получить содержимое буффера char* mbBuffer с такой же кодировкой какая была при чтении из файла. Никак не удаётся преобразовать.
PM MAIL   Вверх
Andrey44
Дата 11.12.2007, 15:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Попробуй может быть CW2A  и  CA2W.
Первый конвертит из второй в юникод.


--------------------
????? ??, ??????? ?????.  smile 
PM MAIL WWW ICQ   Вверх
SAVe
Дата 11.12.2007, 16:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Да вот собственно перекодировать строку удалось таким вот  топорным способом:

Код

char* mbBuffer;
    LPCTSTR mbBuffer_ptr = (LPCTSTR)this->docOut;
    // Необходимый  размер буффера для Unicod строки. 
    // Функция вызванная с такими параметрами его вернёт
    int wcBuffLen = MultiByteToWideChar(1251,0,mbBuffer_ptr,-1,NULL,0);
    wchar_t* wcBuffer = new wchar_t[wcBuffLen];
    // Преобразуем в Unicod
    MultiByteToWideChar(1251,0,mbBuffer_ptr,-1,wcBuffer,wcBuffLen);
    
    
    int mbBuffLen = WideCharToMultiByte(CP_UTF8,0,wcBuffer,-1,NULL,0,NULL,NULL);
    mbBuffer = new char[mbBuffLen + 1];
    WideCharToMultiByte(CP_UTF8,0,wcBuffer,wcBuffLen,mbBuffer,mbBuffLen,NULL,NULL);
    mbBuffer[mbBuffLen]=0;

    this->docOut = mbBuffer;
    
    delete[] mbBuffer;
    delete[] wcBuffer;


Но при сохранении в файл первый символ прописывается не такой как в файле из которого я читаю. В файле из которого читаю 0хEFBB , а в том файле который записан 0хFF60. Поэтому в эксплорере полученный файл не открывается. Если удалить первый символ - открывается. И содержимое корректное. Как заставить его записывать такой же символ как в исходном файле (признак кодировки как я понимаю) ?
PM MAIL   Вверх
NiJazz
Дата 11.12.2007, 18:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Jazz coder
****


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

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



А что, просто сериализовать (т.е. преобразовать в BYTE[]) и записать нельзя?  smile 
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Visual C++/MFC/WTL | Следующая тема »


 




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


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

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