getline () неправильно читает символы с акцентами - PullRequest
3 голосов
/ 29 мая 2019

Я пытаюсь получить акцентированные символы от пользователя с помощью команды 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;
}

Когда я печатаю: Марк Корасао, вот что я получаю:

Accented characters aren't displaying correctly

Как мне это исправить?

Ответы [ 2 ]

3 голосов
/ 29 мая 2019

На самом деле проблема не в 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;

Выход:

Coração


Чтобы заставить его работать с getline():

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

Надеюсь, это поможет.

2 голосов
/ 29 мая 2019

Есть 2 уровня в одной задаче. Проблема в том, что вы используете символы вне кодировки ASCII. 2 уровня:

  • как они преобразуются в узкие символы при вводе
  • как они будут отображаться на выходе

Консоль Windows является довольно тревожным приложением в этом отношении: она может внутренне обрабатывать символы UCS2, которые являются любыми символами Юникода в базовой многоязычной плоскости, иначе говоря, любым символом с точкой кода не более 0xFFFF. При вводе в узкие символы он пытается сопоставить любой символ, не представленный в текущем наборе символов, с тем, что он считает более близким, при выводе он просто выводит значение каждого байта в своем текущем наборе символов. Таким образом, самый надежный способ - убедиться, что текущая локаль имеет правильную последовательность сортировки и что консоль имеет правильную кодовую страницу (кодировка на языке Windows). После просмотра отображаемого вывода я предполагаю, что вы используете кодовую страницу 437, которая содержит полуграфические символы, но мало не ascii.

Поскольку вам нужны только западноевропейские символы, я бы посоветовал вам использовать кодовую страницу 1252. Это вариант Windows стандартной кодировки Latin1 или ISO-8859-1 (символы с кодовой точкой не более 0xFF).

Так что, если возможно, вы должны попытаться настроить систему на неанглийском западноевропейском языке (с португальским было бы хорошо, но французского вполне достаточно, поэтому я бы предположил, что и с испанским тоже будет).

И вы должны настроить консоль на правильную кодовую страницу: chcp 1252.

Если этого недостаточно (в настоящее время я ничего не могу проверить), вы можете попробовать использовать широкие символы (wstring, wcin, wcout). Но без изменения кодовой страницы с 437 консоль не будет отображать акцентированный символ.

...