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

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

我正在尝试在我的 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;
}

test.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
c++ c++20 getline wstring wifstream
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()
并且工作正常。

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