我正试图从控制台阅读西里尔文(“Иванчоговорисамоглупости”),但我得到的只是“????”。我第一次用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;
}
答案 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::cin
和std::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;
}
感谢所有给我建议。