我不明白为什么我的 std::string 字符串没有正确包含 UTF-8 字符串

I don't understand why my std::string string is not containing the UTF-8 string correctly

提问人:DM Perez 提问时间:3/6/2023 最后编辑:Remy LebeauDM Perez 更新时间:3/22/2023 访问量:370

问:

编辑:我正在编辑我的问题,以便通过代码为每个人提供有关我的问题的更清晰的信息。我还将我的输入字符串从日语更改为希腊语字符串,因此请注意。谢谢!


我在下面有这个输入:wstring

wstring command = L"Σὲ γνωρίζω ἀπὸ τὴν κόψη";

这是将 :std::wstringstd::string

string wstring2string(const wstring& str) 
{
   string str2(str.length(), L' ');
   std::copy(str.begin(), str.end(), str2.begin());
   return str2;
}

在此函数之后,字符串中的值变为如下所示:

£r ³½ÉÁw¶É 

Debugged string values here

此函数适用于非 UTF-8 和非 Unicode 文本。我只是无法理解为什么它也不能处理 UTF-8 文本。

C++ 字符串 编码 UTF-8 WSTRING

评论

0赞 Ted Lyngmo 3/6/2023
“字符串在 std::string 容器中穿过几个函数,直到它到达我正在创建的函数” - 这些函数中的任何一个是否通过非引用获取字符串?如果是这样,我怀疑其中之一正在更改字符串。const
0赞 DM Perez 3/6/2023
嗨,@TedLyngmo!感谢您来到线程中。你的意思是“const std::string”形式吗?是的,我相信所有其他函数都直接使用'std::string'。他们都应该使用“const”引用吗?这是否意味着我需要修改所有这些功能?谢谢!
2赞 user17732522 3/6/2023
std::string只是一个字节字符串。它不包含有关编码的任何信息。调试器无法知道您打算让字符串保存什么编码,并且它可能做出了与 UTF-8 不同的假设。您是否检查过调试器为您提供的数值字节值是否是您的字符串应采用 UTF-8 编码的字节值?
1赞 DM Perez 3/6/2023
嗨,@user17732522肖恩·拉姆齐和大家好!感谢您通过此线程支持我!我非常感谢。通过您的回复,我意识到我没有向您提供有关该问题的所有详细信息。请稍等,我创建了一个最小的可重现示例,以便你们都对问题有足够的了解。我会尽快修改问题。谢谢大家!
3赞 j6t 3/7/2023
std::copy不执行任何宽字符串到 UTF-8 字符串的转换。您看到的只是 Unicode 码位的高字节被截断,因此每个字符只保留最低有效 8 位。

答:

4赞 user17732522 3/8/2023 #1

这是将 std::wstring 转换为 std::string 的现有代码(请注意:我没有创建此代码)。

该函数只是将每个代码单元从原始字符串复制到输出字符串,根据 和 的整数属性隐式转换代码单元的数值。实际上,这意味着所有代码单元都被简单地截断到最低字节,从而丢失了所有其他信息。该函数不考虑任何编码或任何东西。它完全坏了。wchar_tchar

要从 to 转换,您首先应该知道输入和输出的编码方式(例如,系统的宽和窄执行字符集编码),然后您应该使用在这两种编码之间提供转码的 unicode 库。std::wstringstd::string

C++标准库确实有它的函数(https://en.cppreference.com/w/cpp/locale/wstring_convert),但由于安全和规范问题,它们已被弃用,因此不应谨慎使用或使用。

如果要从本机宽字符集编码转换为当前 C 区域设置的窄多字节编码,也可以使用 https://en.cppreference.com/w/cpp/string/multibyte/wcsrtombs,但还必须注意确保设置了正确的区域设置。

一个非常完整的 unicode 解决方案是 ICU,但对于您在这里要求的内容,您只需要其中的一小部分。

在 POSIX 系统上有 .iconv

您也可以找到第三方库。

评论

0赞 DM Perez 3/8/2023
哇,非常感谢你!我非常感谢。我想我理解了这个问题,并将尝试推荐的解决方案。会带着结果回到这里。谢谢!
0赞 user17732522 3/8/2023
@DMPerez 请注意,我不建议使用我链接的任何标准库函数。我建议您寻找一个不共享标准库函数问题的第三方库。最完整的 unicode 支持可能是 ICU,但对于解码/编码,您只需要其中的一小部分。在 POSIX 系统上,iconv 是系统的一部分。
0赞 DM Perez 3/8/2023
注意到了。谢谢!