Преобразовать const char * в wstring

Я работаю над собственным расширением для флеш-приложения на основе цинка, и мне нужно преобразовать const char* в wstring.

Это мой код:

mdmVariant_t* appendHexDataToFile(const zinc4CallInfo_t *pCallInfo, int paramCount, mdmVariant_t **params) {

    if(paramCount >= 2) {
        const char *file    = mdmVariantGetString(params[0]);
        const char *data    = mdmVariantGetString(params[1]);

        return mdmVariantNewInt(native.AppendHexDataToFile(file, data));
    }
    else {
        return mdmVariantNewBoolean(FALSE);
    }
}

Но native.AppendHexDataToFile() требуется два wstring. Я не очень хорошо разбираюсь в С++, и я думаю, что все эти разные типы строк совершенно сбивают с толку, и я не нашел в сети ничего полезного. Поэтому я прошу вас, ребята, как это сделать.

Изменить: Строки - это UTF-8, и я использую OSX и Windows XP/Vista/7

Ответ 1

Я рекомендую вам использовать std::string вместо строк в стиле C (char*) везде, где это возможно. Вы можете создать объект std::string из const char*, просто передав его конструктору.

Получив std::string, вы можете создать простую функцию, которая преобразует std::string, содержащий многобайтовые символы UTF-8, в std::wstring, содержащий точки в кодировке UTF-16 (16-битное представление специальных символов из std::string).

Есть и другие способы, как это сделать, например, с помощью функции MultiByteToWideChar:

std::wstring s2ws(const std::string& str)
{
    int size_needed = MultiByteToWideChar(CP_UTF8, 0, &str[0], (int)str.size(), NULL, 0);
    std::wstring wstrTo( size_needed, 0 );
    MultiByteToWideChar(CP_UTF8, 0, &str[0], (int)str.size(), &wstrTo[0], size_needed);
    return wstrTo;
}

Также проверьте эти вопросы:
Отображение многобайтовых символов в их представление точки в юникоде
Зачем использовать MultiByteToWideCharArray для преобразования std::string в std::wstring?

Ответ 2

AFAIK это работает только с С++ 11 и выше:

#include <codecvt>

// ...

std::wstring stringToWstring(const std::string& t_str)
{
    //setup converter
    typedef std::codecvt_utf8<wchar_t> convert_type;
    std::wstring_convert<convert_type, wchar_t> converter;

    //use converter (.to_bytes: wstr->str, .from_bytes: str->wstr)
    return converter.from_bytes(t_str);
}

Справочный ответ

Ответ 3

Вы можете преобразовать строку char в wstring непосредственно в виде следующего кода:

char buf1[] = "12345678901234567890";
wstring ws(&buf1[0], &buf1[20]);

Ответ 4

Вам нужна библиотека, которая может кодировать/декодировать UTF8. К сожалению, эта функция не включена в библиотеку std С++. Здесь можно использовать одну библиотеку: http://utfcpp.sourceforge.net/

Вот пример использования:

utf8::utf8to32(bytes.begin(), bytes.end(), std::back_inserter(wstr));

Ответ 5

Дополнение к ответу от @anhoppe. Вот как конвертировать char*:

#include <codecvt>
#include <locale> 

// ...

std::wstring stringToWstring(const char* utf8Bytes)
{
    //setup converter
    using convert_type = std::codecvt_utf8<typename std::wstring::value_type>;
    std::wstring_convert<convert_type, typename std::wstring::value_type> converter;

    //use converter (.to_bytes: wstr->str, .from_bytes: str->wstr)
    return converter.from_bytes(utf8Bytes);
}

А вот как конвертировать char*, если вы уже знаете длину буфера:

#include <codecvt>

// ...

std::wstring stringToWstring(const char* utf8Bytes, const size_t numBytes)
{
    //setup converter
    using convert_type = std::codecvt_utf8<typename std::wstring::value_type>;
    std::wstring_convert<convert_type, typename std::wstring::value_type> converter;

    //use converter (.to_bytes: wstr->str, .from_bytes: str->wstr)
    return converter.from_bytes(utf8Bytes, utf8Bytes + numBytes);
}

Ответ 6

В OS X wstring использует UTF-32, а не UTF-16. Вы можете сделать преобразование следующим образом:

#include <codecvt>
#include <string>

// make facets usable by giving them a public destructor
template <class Facet>
class usable_facet
    : public Facet
{
public:
    template <class ...Args>
        usable_facet(Args&& ...args)
            : Facet(std::forward<Args>(args)...) {}
    ~usable_facet() {}
};

std::wstring s2ws(std::string const &s) {
    std::wstring_convert<
        usable_facet<std::codecvt<char32_t,char,std::mbstate_t>>
        ,char32_t> convert;
    std::u32string utf32 = convert.from_bytes(s);
    static_assert(sizeof(wchar_t)==sizeof(char32_t),"char32_t and wchar_t must have same size");
    return {begin(utf32),end(utf32)};
}

Ответ 7

Вот код, который я нашел;

std::wstring StringToWString(const std::string& s)
 {
 std::wstring temp(s.length(),L' ');
 std::copy(s.begin(), s.end(), temp.begin());
 return temp; 
 }

И здесь исходный пост форума с возможным вторым решением, использующим функцию API окон MultiByteToWideChar:

http://forums.codeguru.com/archive/index.php/t-193852.html