在 Linux 中将 std::string 转换为 Unicode
Convert std::string to Unicode in Linux
>编辑 在意识到一开始是错误的后,我修改了这个问题。
我正在将 C# 应用程序的一部分移植到 Linux,我需要在其中获取 UTF-16 字符串的字节:
string myString = "ABC";
byte[] bytes = Encoding.Unicode.GetBytes(myString);
因此,bytes
数组现在为:
"65 00 66 00 67 00" (bytes)
如何在 Linux 上的C++中实现相同的目标?我有一个定义为 std::string
的myString
,似乎 Linux 上的std::wstring
是 4 个字节?
你的问题不是很清楚,但我会试着澄清一些困惑。
介绍
在95 年对 C 标准进行修订后处理 C 语言字符集的状态(由 C++ 继承
)。使用的字符集由当前区域设置给出
wchar_t
用于存储代码点char
用于存储多字节编码形式(例如,约束是基本字符集中的字符必须编码在一个字节中)字符串文本以实现定义的方式进行编码。 如果它们使用基本字符集之外的字符,则不能假定它们在所有区域设置中都有效。
因此,对于 16 位wchar_t
您仅限于 BMP。 使用 UTF-16 的代理项是不合规的,但我认为 MS 和 IBM 或多或少被迫这样做,因为他们相信 Unicode,当他们说他们将永远是一个 16 位字符集时。 那些延迟支持Unicode的人倾向于使用32位wchar_t。
较新的标准不会有太大变化。 大多数情况下,有 UTF-8、UTF-16 和 UTF-32 编码字符串的文字,也有 16 位和 32 位字符的类型。 标准库中对 Unicode 的额外支持很少或没有。
如何将一种编码转换为另一种编码
您必须处于使用 Unicode 的区域设置中。 希望
std::locale::global(locale(""));
这就足够了。 否则,您的环境未正确设置(或针对另一个字符集进行设置,并假设 Unicode 不会为您的用户提供服务)。
C 样式
使用wcstomsb
和mbstowcs
功能。 这是您询问的示例。
std::string narrow(std::wstring const& s)
{
std::vector<char> result(4*s.size() + 1);
size_t used = wcstomsb(&result[0], s.data(), result.size());
assert(used < result.size());
return result.data();
}
C++风格
区域设置的编解码器方面提供了所需的功能。 优点是您无需更改全局区域设置即可使用它。 不方便的是用法比较复杂。
#include <locale>
#include <iostream>
#include <string>
#include <vector>
#include <assert.h>
#include <iomanip>
std::string narrow(std::wstring const& s,
std::locale loc = std::locale())
{
std::vector<char> result(4*s.size() + 1);
wchar_t const* fromNext;
char* toNext;
mbstate_t state = {0};
std::codecvt_base::result convResult
= std::use_facet<std::codecvt<wchar_t, char, std::mbstate_t> >(loc)
.out(state,&s[0], &s[s.size()], fromNext,
&result[0], &result[result.size()], toNext);
assert(fromNext == &s[s.size()]);
assert(toNext != &result[result.size()]);
assert(convResult == std::codecvt_base::ok);
*toNext = ' ';
return &result[0];
}
std::wstring widen(std::string const& s,
std::locale loc = std::locale())
{
std::vector<wchar_t> result(s.size() + 1);
char const* fromNext;
wchar_t* toNext;
mbstate_t state = {0};
std::codecvt_base::result convResult
= std::use_facet<std::codecvt<wchar_t, char, std::mbstate_t> >(loc)
.in(state, &s[0], &s[s.size()], fromNext,
&result[0], &result[result.size()], toNext);
assert(fromNext == &s[s.size()]);
assert(toNext != &result[result.size()]);
assert(convResult == std::codecvt_base::ok);
*toNext = L' ';
return &result[0];
}
您应该通过更好的处理来替换断言。
顺便说一句,这是标准C++并且不假设 Unicode 除了计算结果大小之外,您可以通过检查可以指示部分转换的 convResult 做得更好)。
最简单的方法是获取一个小库,例如 UTF8 CPP 并执行以下操作:
utf8::utf8to16(line.begin(), line.end(), back_inserter(utf16line));
我通常使用Poco C++库中的UnicodeConverter类。如果你不想要依赖关系,那么你可以看看代码。
- 将ANSI C字符串转换为UNICODE
- 删除unicode def后,无法将QString转换为TCHAR
- 如何将整数转换为 unicode 字符
- 如何将小数NCR转换为Unicode字符(C )
- Ubuntu上的库ICU不想从Unicode转换为Windows-1251
- 如何在Unicode/UCS CodePoint和UTF16替代对之间转换
- Unicode 字符问题/转换参数
- 将ISO 8859-X转换为Unicode的方法
- 如何在Visual C 中的BSTR和32位Unicode字符串之间进行转换
- 在 unicode 中将 WCHAR 数组转换为 std::string?
- ANSI到Unicode或向后转换:怎么可能?
- 从ASCII到Unicode字符代码的转换(FreeType2)
- 将 unicode 字符串转换为字符串
- 如何在Django中将unicode转换为C++std::string
- 字符串转换:MBCS <-> UNICODE,内有多个 \0
- 在 UNICODE 应用程序中将 char * 转换为 catch 块内的 CString
- 如何在c++中将unicode代码点转换为utf-8
- 如何将无符号十六进制值转换为相应的unicode字符,这些字符应该使用c++写入文件
- C++将ASII转义的unicode字符串转换为utf8字符串
- 将 STL unicode 字符串转换为 wxString 会给出空字符串