[C++]:访问 wstring 中的单个字符 (wchar_t)

问题描述 投票:0回答:1

我正在从包含 unicode 字符的文件中读取文本,并将文本存储到 wstring 中。我有兴趣迭代 wstring 以确定哪些字符需要多个字节来存储。

我的问题是

str.length()
其中str是wstring)似乎指示字符串中的字节数而不是字符数。另外,当我使用
str[i]
迭代字符串时,括号运算符似乎只返回 1 个字节。

这是一些复制我的问题的示例代码:

wifstream inFile;
inFile.open(L"myFile.txt");
    
wstring str;
getline(inFile, str);

wcout << str.length() << endl;
for (unsigned int i = 0; i < str.length(); i++) {
  wcout << str[i] << L" (" << (unsigned int)str[i] << L')' << endl;
}

wofstream outFile;  outFile.open(L"outFile.txt");
outFile << str << endl;

outFile.close();
inFile.close();

代码输出:

5
H (72)
├ (195)
í (161)
l (108)
o (111)

我尝试使用包含字符串

"Hálo"
的文件。
str.length()
报告 5,这似乎是存储字符串所需的最小字节数(假设您对除 á 之外的所有字符使用一个字节)。这让我很困惑,因为在我的环境中
sizeof(wchar_t)
是 2。我认为 wstring 中的 4 个字符数组至少需要 8 个字节。然而,似乎
"Hálo"
被存储为
01001000 {11000011 10100001} 01101100 01101100
大括号表示unicode字符)。因此,当我迭代此操作时,我得到的所有内容都返回了,就好像它们只是
char
并且 unicode 字符
á
返回为 2 个字符
á

奇怪的是,当我将 wstring 写入文件时(在上面的代码中看到),文本按预期显示,并且正确解释了 unicode 字符。

有没有办法迭代 wstring 中的实际字符而不仅仅是字节?另外,为什么 wstring 仅将其存储在 5 个字节而不是 8 个字节中?我认为它节省了空间,但它使访问元素看起来不直观。

编辑:我知道我的终端可能无法正确显示 wchar_t,尽管我仍然希望打印它的整数值。

c++ iteration wchar-t wstring
1个回答
0
投票

您所说的关于

std::wstring
的一切都是不正确的。它不存储 bytes,并且它的
length()
不以 bytes 表示(这些对于
std::string
来说是正确的)。

std::wstring
保存
wchar_t
个字符,其
length()
是字符串中
wchar_t
元素的数量。根据定义,
sizeof(wchar_t) > sizeof(char)
,在 Windows 上
wchar_t
为 2 个字节(用于 UCS-2/UTF-16),而在其他平台上
wchar_t
为 4 个字节(用于 UTF-32)。

要使用

std::wstring
将文件读入
std::wifstream
,您需要将正确的
imbue()
放入
std::locale
来处理文件的编码(ANSI、UTF-8 等),以便可以对其进行解码变成
std::wifstream
个字符。
在您的情况下,您的文件以 UTF-8 编码,因为 

wchar_t

的 UTF-8 编码形式是字节序列:

Hálo

由于您的 
H - 0x48 á - 0xC3 0xA1 l - 0x6C o - 0x6F

不知道数据是 UTF-8,因此它只是将每个字节按原样升级为

std::wifstream
。您需要将 UTF-8 语言环境添加到流中才能正确读取此文件。
    

© www.soinside.com 2019 - 2024. All rights reserved.