未能找到 std::wstring 中存在的 wchar_t
Failing to find a wchar_t that is present in a std::wstring
我在玩 std::wstring
和 std::wfstream
时遇到了一个奇怪的行为。也就是说,std::basic_string<wchar_t>::find
似乎无法找到某些字符。考虑以下代码:
int main()
{
std::wifstream input("input.txt");
std::wofstream output("output.txt");
if(!(input && output)){
std::cerr << "file(s) not opened";
return -1;
}
std::wstring buf;
std::getline(input, buf);
output << buf;
std::cout << buf.find(L'ć');
}
这里我只是简单的读取了input
文件的第一行,写入到output
文件中。程序运行前,第一个文件的内容为aąbcćd
,输出文件为空。执行代码后,输入文件成功复制到输出文件中。
令我惊讶的是,我试图在 buf
中找到一个 ć
字母,但遇到了上述奇怪的行为。程序执行后,我确认输出文件中确实包含 aąbcćd
,其中显然包含提到的字符 ć
.
然而,std::cout << buf.find(L'ć')
行没有按预期运行。考虑到 std::wstring
的内存布局,我没想到会得到 4
的输出,但我也 绝对没想到会得到 std::string::npos
.值得一提的是,用这个方法找正则ASCII字符是成功的。
综上所述,上述代码正确地将输入文件的第一行复制到输出文件,但未能在字符串中找到负责保存数据的字符(返回npos)复制。为什么?是什么导致 find
在这里失败?
注意:两个文件都是 Windows.
上的 UTF-8 编码
不幸的是,wchar_t
不是 UTF-8,而是 UTF-16(在 Windows 上),当您读取 UTF-8 文件时,不会发生神奇的转换。如果您调试程序,您会在 buf
变量中看到损坏的字符。
您需要将字符串读取为 std::string
然后从 UTF-8 转换为 whar_t
或使用 UTF-8 并将文字字符串从 whcar_t
转换为 std::string
个 UTF-8 字符。
如果您使用的是最新的编译器,您可以使用以下命令创建 UTF-8 字符串文字:
u8"ć"
以下应该有效:
int main()
{
std::ifstream input("input.txt");
std::ofstream output("output.txt");
if(!(input && output)){
std::cerr << "file(s) not opened";
return -1;
}
std::string buf;
std::getline(input, buf);
output << buf;
std::cout << buf.find(u8"ć");
}
我在玩 std::wstring
和 std::wfstream
时遇到了一个奇怪的行为。也就是说,std::basic_string<wchar_t>::find
似乎无法找到某些字符。考虑以下代码:
int main()
{
std::wifstream input("input.txt");
std::wofstream output("output.txt");
if(!(input && output)){
std::cerr << "file(s) not opened";
return -1;
}
std::wstring buf;
std::getline(input, buf);
output << buf;
std::cout << buf.find(L'ć');
}
这里我只是简单的读取了input
文件的第一行,写入到output
文件中。程序运行前,第一个文件的内容为aąbcćd
,输出文件为空。执行代码后,输入文件成功复制到输出文件中。
令我惊讶的是,我试图在 buf
中找到一个 ć
字母,但遇到了上述奇怪的行为。程序执行后,我确认输出文件中确实包含 aąbcćd
,其中显然包含提到的字符 ć
.
然而,std::cout << buf.find(L'ć')
行没有按预期运行。考虑到 std::wstring
的内存布局,我没想到会得到 4
的输出,但我也 绝对没想到会得到 std::string::npos
.值得一提的是,用这个方法找正则ASCII字符是成功的。
综上所述,上述代码正确地将输入文件的第一行复制到输出文件,但未能在字符串中找到负责保存数据的字符(返回npos)复制。为什么?是什么导致 find
在这里失败?
注意:两个文件都是 Windows.
上的 UTF-8 编码不幸的是,wchar_t
不是 UTF-8,而是 UTF-16(在 Windows 上),当您读取 UTF-8 文件时,不会发生神奇的转换。如果您调试程序,您会在 buf
变量中看到损坏的字符。
您需要将字符串读取为 std::string
然后从 UTF-8 转换为 whar_t
或使用 UTF-8 并将文字字符串从 whcar_t
转换为 std::string
个 UTF-8 字符。
如果您使用的是最新的编译器,您可以使用以下命令创建 UTF-8 字符串文字:
u8"ć"
以下应该有效:
int main()
{
std::ifstream input("input.txt");
std::ofstream output("output.txt");
if(!(input && output)){
std::cerr << "file(s) not opened";
return -1;
}
std::string buf;
std::getline(input, buf);
output << buf;
std::cout << buf.find(u8"ć");
}