【问题标题】:How to widen a standard string while maintaining the characters?如何在保持字符的同时加宽标准字符串?
【发布时间】:2018-12-21 03:39:24
【问题描述】:

我有一个函数来获取std::string 并将其更改为wchar_t*。我现在的加宽函数是这样的

wchar_t* widen(const std::string& str){  
    wchar_t * dest = new wchar_t[str.size()+1];
    char * temp = new char[str.size()];
    for(int i=0;i<str.size();i++)
        dest[i] = str[i];
    dest[str.size()] = '\0';
    return dest;
}  

这适用于标准字符,但是(我不敢相信这在以前不是问题)当我有 á、é、í、ó、ú、ñ 或 ü 之类的字符时,它会中断并且结果大不相同。
例如:我的str 输入为"Database Function: áFákéFúnctíóñü"
但是dest 最终会变成:"Database Function: £F£k←Fnct■￳￱"

如何在保持国际字符的同时从std::string 更改为wchar_t*

【问题讨论】:

  • 请注意您的代码:在大多数情况下,当您使用手动内存管理(即不使用智能指针)或使用矢量new 时,您做错了.在此处使用标准容器(向量、字符串、wstring)。
  • @UlrichEckhardt,感谢您的说明。这个特殊的项目在大多数地方都在 10 到 14 岁之间,我有幸在过去一年左右的时间里涉足它,更不幸的是,由于向后兼容的必要性,我无法修复旧的东西坏了

标签: c++11 stdstring wchar-t


【解决方案1】:

简短的回答:你不能。

更长的答案:std::string 包含 char 元素,这些元素通常在前 127 个值中包含 ASCII,而其他所有内容(“国际字符”)都在上面的值中(或负数,如果 char 已签名)。为了确定wchar_t 字符串中的相应表示,您首先需要知道源字符串中的编码(可以是 ISO-8859-15 甚至 UTF-8)和目标字符串中的编码(通常是 UTF- 16, UCS2 或 UTF-32),然后进行相应的转码。

【讨论】:

  • 是的,“知道源字符串中的编码……以及目标字符串中的编码……然后进行相应的转码。”这使得与 ASCII 的任何相似性——甚至 ASCII 的存在——都无关紧要。
【解决方案2】:

这取决于源是使用旧的 ANSI 代码页还是 UTF8。对于 ANSI 代码页,您必须知道语言环境,并使用 mbstowcs。对于 UTF8,您可以使用 codecvt_utf8_utf16 转换为 UTF16。但是codecvt_utf8_utf16 已被弃用,目前还没有替代品。在 Windows 中,您可以使用 WinAPI 函数使转换更加可靠。

#include <iostream>
#include <string>
#include <codecvt>

std::wstring widen(const std::string& src)
{
    int len = src.size();
    std::wstring dst(len + 1, 0);
    mbstowcs(&dst[0], src.c_str(), len);
    return dst;
}

int main()
{
    //ANSI code page?
    std::string src = "áFákéFúnctíóñü";
    setlocale(LC_ALL, "en"); //English assumed
    std::wstring dst = widen(src);
    std::wcout << dst << "\n";

    //UTF8?
    src = u8"áFákéFúnctíóñü";
    std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>, wchar_t> convert;
    dst = convert.from_bytes(src);
    std::wcout << dst << "\n";

    return 0;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-01-19
    • 2021-03-17
    • 2013-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多