Как преобразовать CString в unsigned char* с помощью Unicode?

Я пытаюсь сделать что-то простое здесь. Когда я выполняю следующий код в Visual Studio 2008 с использованием набора символов Unicode, xmlString является правильным.

К сожалению, мне нужно преобразовать CString в беззнаковый char*. Используя приведенный ниже код, ucStr становится «‹» (т. е. первым символом xmlString).

Как преобразовать CString в беззнаковый символ* и сохранить всю информацию?

        CString xmlString;
        xmlString.Format( _T("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?><gateway><config-read><%s /></config-read></gateway>"), keyName);

        unsigned char * ucStr = reinterpret_cast<unsigned char *> (xmlString.GetBuffer());
        pgIRequest->SendXmlData( "dgv/gateway.xml", ucStr, xmlString.GetLength() + 1) ; 

person Community    schedule 28.01.2009    source источник
comment
Я думаю, что хорошим чтением по этому поводу была бы статья Джоэла о юникоде с броским названием «Абсолютный минимум, который каждый разработчик программного обеспечения обязательно должен знать о юникоде и наборах символов (без оправданий!): joelonsoftware.com/articles/Unicode.html   -  person vividos    schedule 29.01.2009


Ответы (5)


Я считаю, что проще всего использовать конструктор CStringA, например:

    CString xmlString;
    xmlString.Format( _T("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?><gateway><config-read><%s /></config-read></gateway>"), "test");

    printf("%s\n",xmlString );  // fails "<"

    //unsigned char * ucStr = reinterpret_cast<unsigned char *> (xmlString.GetBuffer());

    CStringA ucStr( xmlString );

    printf("%s\n",ucStr );   // works!
person ravenspoint    schedule 28.01.2009
comment
Это не сохранит всю информацию. Т.е. он удалит все незападные символы. Вам нужно конвертировать в UTF-8. - person Nemanja Trifunovic; 29.01.2009

Этот фрагмент кода может не работать, если ваша переменная 'keyName' начинает содержать символы, которые не могут быть представлены в кодировке ISO-8859-1. Для этого я рекомендую создать строку с UTF-8 в качестве значения кодировки, преобразовать в поток байтов UTF-8, используя WideCharToMultiByte, используя кодовую страницу CP_UTF8, и отправить результирующий поток байтов utf8.

person vividos    schedule 28.01.2009

Я думаю, вам нужны wcstombs или, скорее, , его более безопасный аналог wcstombs_s.

person Reunanen    schedule 28.01.2009

Я предполагаю, что «SendXmlData» хочет количество байтов, а не количество символов.

Если это так, вы хотите изменить «GetLength() + 1» на «(GetLength() + 1)*sizeof(xmlString[0])».

person KenE    schedule 28.01.2009
comment
ucStr становится '‹' -- да, если это наблюдалось в отладчике, то ответ KenE может быть полезен. Но если бы это было отмечено в приемнике (или подобном), то доступных данных должно было быть гораздо больше. - person Reunanen; 29.01.2009
comment
Пукку прав, длина буфера в SendXmlData не имеет ничего общего с моей проблемой — см. код, который у меня работает ниже. - person ; 29.01.2009
comment
Что ж, теперь, когда строка фактически была преобразована, xmlString.GetLength() тоже подходит — она должна возвращать то же самое, что и ucStr.GetLength() вашей рабочей версии. Так что это не совсем доказательство против предложения Кени. Кстати, убедитесь, что вы тестируете также такие входные данные, которые не могут быть представлены в ASCII. - person Reunanen; 29.01.2009

Вот код, который, наконец, сработал:

CString xmlString;
        xmlString.Format( _T("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?><gateway><config-read><%s /></config-read></gateway>"), keyName);
        CStringA ucStr( xmlString );
        unsigned char * ucStr2 = reinterpret_cast<unsigned char *> (ucStr.GetBuffer());
        pgIRequest->SendXmlData( "dgv/gateway.xml", ucStr2, xmlString.GetLength() + 1) ;// target on gateway to download
person Community    schedule 28.01.2009