从Console C ++中读取西里尔语

时间:2016-11-03 17:30:55

标签: c++

我正试图从控制台阅读西里尔文(“Иванчоговорисамоглупости”),但我得到的只是“????”。我第一次用C ++写作,如果有人帮助我解决这个问题,我会非常感激。

这是我的代码

#include<iostream>
#include<string>
#include<map>
#include<Windows.h>
#include<clocale>

using namespace std;

bool CheckLetters(int letter)
{
    SetConsoleCP(1251);
    SetConsoleOutputCP(1251);

    bool isCyrillic = ('\u0410' <= letter && letter <= '\u044f');
    if ((letter >= 'a' && letter <= 'z')
        || (letter >= 'A' && letter <= 'Z')
        || isCyrillic)
    {
        return true;
    }
    return false;
}

int main()
{
    string input;
    map<unsigned char, int> letters;

    getline(cin, input);

    for (int i = 0; i < input.size(); i++)
    {
        unsigned char currentLetter = input[i];
        if (CheckLetters(currentLetter))
        {
            map<unsigned char, int>::iterator elementIter = letters.find(currentLetter);
            if (elementIter == letters.end())
            {
                letters[currentLetter] = 1;
            }
            else
            {
                letters[currentLetter] ++;
            }
        }

    }

    for (map<unsigned char, int>::iterator current = letters.begin();
         current != letters.end(); current++)
    {
        pair<unsigned char, int> currentElement = *current;
        cout << currentElement.first << " " << currentElement.second <<endl;
    }

    return 0;
}

enter image description here

3 个答案:

答案 0 :(得分:3)

建议使用Unicode而不是将代码页更改为俄语或任何特定语言。 Windows API使用UTF16,遗憾的是Windows控制台的Unicode支持有限。这是一个特定于Windows控制台和Visual Studio的解决方案(例如,它不能使用MinGW)。它仍然不会使用一些亚洲语言(或者至少我不知道如何使它工作)

#include <iostream>
#include <string>
#include <io.h> //for _setmode
#include <fcntl.h> //for _O_U16TEXT

int main() 
{
    _setmode(_fileno(stdout), _O_U16TEXT);
    _setmode(_fileno(stdin), _O_U16TEXT);
    std::wcout << L"ελληνικά Иванчо English\n";

    std::wstring str;
    std::wcin >> str;
    std::wcout << "output: " << str << "\n";

    return 0;
}

请注意,将模式更改为UTF16后,您无法使用std::cinstd::cout。如果要继续使用ANSI输入/输出,则必须将模式设置回_O_TEXT。例如:

_setmode(_fileno(stdout), _O_TEXT);
_setmode(_fileno(stdin), _O_TEXT);
std::cout << "Test\n";

在UTF16中接收输入后,您可能希望使用WideCharToMultiByte(CP_UTF8, ...)转换为UTF8(存储在char中)以与网络功能等兼容。

答案 1 :(得分:2)

这种组合怎么样?

setlocale(LC_ALL, "Russian");
SetConsoleOutputCP(866);

答案 2 :(得分:1)

我的主要问题是,我在开始时没有在VS中设置编码。所以,我创建新项目并将代码页设置为1251.这是我的代码:

#include<iostream>
#include<string.h>
#include<map>
#include<windows.h>
#include<locale>

using namespace std;

bool CheckLetters(wchar_t letter)
{
    bool isCyrillic = 65472 <= letter && letter <= 65535;
    if ((letter >= 'a' && letter <= 'z')
        || (letter >= 'A' && letter <= 'Z')
        || isCyrillic)
    {
        return true;
    }
    return false;
}


int main()
{

    SetConsoleCP(1251);
    SetConsoleOutputCP(1251);

    wstring input;
    map<wchar_t, int> letters;

    getline(wcin, input);

    for (int i = 0; i < input.size(); i++)
    {
        char currentLetter = input[i];

        if (CheckLetters(currentLetter))
        {
            map<wchar_t, int>::iterator elementIter = letters.find(currentLetter);
            if (elementIter == letters.end())
            {
                letters[currentLetter] = 1;
            }
            else
            {
                letters[currentLetter] ++;
            }
        }

    }

    for (map<wchar_t, int>::iterator current = letters.begin();
        current != letters.end(); current++)
    {
        pair<wchar_t, int> currentElement = *current;
        cout << (char)(currentElement.first) << " = " << currentElement.second << endl;
    }

    return 0;
}

感谢所有给我建议。