未能找到 std::wstring 中存在的 wchar_t

Failing to find a wchar_t that is present in a std::wstring

我在玩 std::wstringstd::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"ć");
}