当我遇到奇怪的行为时,我正在玩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'ć')
的行为不符合预期。考虑到4
的内存布局,我没想到会得到std::wstring
的输出,但是我也绝对没想到会得到std::string::npos
。值得一提的是,使用此方法查找常规ASCII字符成功。
总而言之,上述代码正确地将输入文件的第一行复制到输出文件,但是无法在字符串中找到一个字符(返回npos),该字符串负责保存要复制的数据。为什么呢?是什么导致find
在此处失败?
注意:两个文件在Windows上都是UTF-8编码。
答案 0 :(得分:1)
不幸的是,wchar_t
不是UTF-8,它不是UTF-16(在Windows上),并且在读取UTF-8文件时不会发生魔术转换。如果您调试程序,则会在buf
变量中看到损坏的字符。
您要么需要以std::string
的形式读取字符串,然后从UTF-8转换为whar_t
,要么在UTF-8中工作,然后将文字字符串从whcar_t
转换为{{1 }}的UTF-8字符。
如果使用的是最新的编译器,则可以使用以下命令创建UTF-8字符串文字:
std::string
以下方法应该起作用:
u8"ć"