为什么std::getline()似乎会弄乱带重音的字符?

4
我正在尝试在我的C++20程序中使用和显示法语重音字符。
然而,使用std::getline()来读取文件内部似乎会弄乱重音字符,就像这样:
#include <locale>
#include <iostream>
#include <fstream>

int main(void)
{
    setlocale(LC_ALL,"");
    std::wifstream  file("test.txt");
    std::wstring    s;
    std::getline(file, s);
    std::wcout << s << std::endl;
    return 0;
}

测试.txt的内容(以UTF-8编码)

Salut ! Comment ça va ? éèêëâàäáôûöüùîï

结果:

$>./test
Salut ! Comment ça va ? éèêëâà äáôûöüùîï

然而,当我尝试将相同的文本显示为const std::wstring时,结果没有任何问题。
#include <locale>
#include <iostream>

int main(void)
{
    setlocale(LC_ALL,"");
    std::wstring    s = L"Salut ! Comment ça va ? éèêëâàäáôûöüùîï";
    std::wcout << s << std::endl;
    return 0;
}

结果:

$>./test
Salut ! Comment ça va ? éèêëâàäáôûöüùîï

使用setlocale(LC_ALL, "")已经使问题得到了改善,因为之前即使第二个例子也无法工作,但是std::getline()似乎存在一个我无法理解的问题。
我读到可能需要将区域设置注入到std::wifstream中,但是我无法理解如何使其工作。
我对C++还比较新,所以不确定是否有更好的工具来解决这类问题,至少我找不到。
我在MinGW上使用zsh,集成在VSCode中。
我使用以下命令进行编译:
c++ -Wall -Wextra -Werror -std=c++20 test.cpp -o test

1
据我所知,你需要使用适当的std::locale来为wifstream设置imbue(),以处理文件的UTF-8编码。setlocale()是不够的。 - undefined
1
我对所提出的问题不确定。test.txt 是以 UTF-8 编码,还是 UTF-16 编码,或者其他编码? - undefined
文件是如何编码的? - undefined
@Eljay 这个txt文件是以UTF-8编码的,我会将它添加到问题中。 - undefined
我在MinGW上使用zsh,集成到VSCode中。 - undefined
显示剩余6条评论
1个回答

0
我能够解决这个问题,多亏了这篇帖子! 注入是解决办法,以下是解决我的问题的方法:
#include <locale>
#include <codecvt>
#include <iostream>
#include <fstream>

int main(void)
{
    setlocale(LC_ALL,"");
    std::wifstream  file("test.txt");
    file.imbue(std::locale(std::locale(), new std::codecvt_utf8<wchar_t,0x10ffff, std::consume_header>));
    std::wstring    s;
    std::getline(file, s);
    std::wcout << s << std::endl;
    return 0;
}

这一行:
file.imbue(std::locale(std::locale(), new std::codecvt_utf8<wchar_t,0x10ffff, std::consume_header>));

原本是:
file.imbue(std::locale(std::locale::empty(), new std::codecvt_utf8<wchar_t,0x10ffff, std::consume_header>));

然而,std::locale::empty()是特定于平台的,如SO问题中所示,所以我用std::locale()替换了它,结果运行良好。

1
codecvt_utf8已被废弃,仅供参考。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接