Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Visual C++/MFC/WTL > Запись CString в файл


Автор: SAVe 11.12.2007, 12:37
Я создал файл (в 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 с такой же кодировкой какая была при чтении из файла. Никак не удаётся преобразовать.

Автор: Andrey44 11.12.2007, 15:37
Попробуй может быть CW2A  и  CA2W.
Первый конвертит из второй в юникод.

Автор: SAVe 11.12.2007, 16:29
Да вот собственно перекодировать строку удалось таким вот  топорным способом:

Код

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. Поэтому в эксплорере полученный файл не открывается. Если удалить первый символ - открывается. И содержимое корректное. Как заставить его записывать такой же символ как в исходном файле (признак кодировки как я понимаю) ?

Автор: NiJazz 11.12.2007, 18:23
А что, просто сериализовать (т.е. преобразовать в BYTE[]) и записать нельзя?  smile 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)