34

我正在为基于锌的闪存应用程序开发本机扩展,我需要将 a 转换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。我对 C++ 不是很好,我认为所有这些不同的字符串类型完全令人困惑,而且我在网络中没有找到有用的东西。所以我问你们怎么做。

编辑:字符串是 UTF-8,我使用的是 OSX 和 Windows XP/Vista/7

4

7 回答 7

23

我建议您尽可能使用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;
}

还要检查这些问题:
Mapping multibyte characters to their unicode point representation
为什么使用 MultiByteToWideCharArray 将 std::string 转换为 std::wstring?

于 2012-05-24T13:09:28.733 回答
16

AFAIK 这仅适用于 C++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);
}

参考答案

更新

正如评论中所指出的,<codecvt> 似乎在 C++17 中已被弃用。请参阅此处:不推荐使用的标头 <codecvt> 替换

于 2015-09-21T14:00:30.770 回答
16

您可以将char字符串wstring直接转换为以下代码:

char buf1[] = "12345678901234567890";
wstring ws(&buf1[0], &buf1[20]);
于 2016-09-15T21:35:53.093 回答
2

您需要一个可以编码/解码 UTF8 的库。不幸的是,这个功能不包含在 std c++ 库中。这是您可能使用的一个库:http: //utfcpp.sourceforge.net/

这是一个使用它的示例:

utf8::utf8to32(bytes.begin(), bytes.end(), std::back_inserter(wstr));
于 2012-05-24T13:14:00.430 回答
0

在 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)};
}
于 2012-05-24T14:12:03.840 回答
0

@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);
}
于 2018-06-28T07:46:09.733 回答
-2

这是我找到的代码;

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

这是使用 Windows API 函数 MultiByteToWideChar 的可能的第二个解决方案的原始论坛帖子:

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

于 2012-05-24T12:43:41.743 回答