getline()无法正确读取带重音符号的字符

时间:2019-05-29 14:04:46

标签: c++ getline non-ascii-characters

我正在尝试使用getline()命令从用户那里获取带重音符号的字符,但是它不能正确打印它们。

我尝试将某些库作为locale包括在内,但没有用。

这是我的代码:

#include <iostream>
#include <cstdlib>
#include <string>
#include <locale>

using namespace std;

class Pers {
public:
    string name;
    int age;
    string weapon;
};

int main()
{
    setlocale(LC_ALL, "");
    Pers pers;

    cout << "Say the name of your character: ";
    getline(cin, pers.name);
    cout << pers.name;
}

当我输入:MarkCoração时,这就是我得到的:

Accented characters aren't displaying correctly

我该如何解决?

2 个答案:

答案 0 :(得分:3)

实际上,问题并非出自getline()

std::cout(分别为std::cin)不支持特殊字符。为此,您必须使用std::wcout(分别为std::wcin),该字符使用宽字符(标准字符的大小将您限制为可以在ascii表中找到的字符)。
您需要也可以使用较大的字符来存储特殊字符,例如宽字符。
std::string处理标准字符,std::wstring处理宽字符。

执行此操作的方法可能是:

std::wstring a(L"Coração");
std::wcout << a << std::endl;

输出:

  

科拉索


要使其与getline()一起使用:

std::wstring a;
getline(std::wcin, a)
std::wcout << a << std::endl;

我希望它能提供帮助。

答案 1 :(得分:2)

在同一问题中有2个级别。问题是您正在使用ASCII字符集以外的字符。这两个级别是:

  • 如何在输入时将它们转换为窄字符
  • 它们如何在输出中显示
在这方面,Windows控制台是一个相当令人不安的应用程序:它能够内部处理UCS2字符,这些字符是基本多语言平面中的任何Unicode字符,换句话说,任何代码点最多为0xFFFF的字符。在输入到狭窄字符中时,它尝试将当前字符集中未表示的任何字符映射到它认为更接近的字符,在输出时,它仅输出其当前字符集中每个字节的值。因此,最可靠的方法是确保当前语言环境具有正确的整理顺序,并且控制台具有正确的代码页(Windows语言的字符集)。看到显示的输出后,我假设您正在使用代码页437,该代码页包含半图形字符,但很少包含非ascii字符。

由于您只需要西欧字符,我建议您使用代码页1252。它是标准Latin1或ISO-8859-1字符集(代码点最多为0xFF的字符)的Windows变体。

因此,如果可能的话,您应该尝试使用非英语西欧语言来配置系统(葡萄牙语可以,但是法语似乎足够,所以我认为西班牙语也可以)。

必须在正确的代码页中配置控制台:chcp 1252

如果这还不够(我目前无法测试任何东西),则可以尝试使用宽字符(wstringwcinwcout)。但是,如果不从437更改代码页,控制台将不会显示带重音符号的字符。