2016-11-03 4 views
0

키릴 문자 ("Иванчо говори само глупости")를 콘솔에서 읽으려고하는데, 내가 얻는 모든 것은 "????"입니다. 처음으로 나는 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

+1

'char' 대신'wchar_t'을 시도 했습니까? –

+0

아니요, 시도해 보겠습니다. –

+0

아니요, wchar_t로 작동하지 않습니다 –

답변

2

입니까?

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

표준 C++가 아닙니다. –

+0

@ πάνταῥεῖ 이것은 콘솔에서 텍스트를 읽는 중입니다. 나는 표준 C++에서 "콘솔"또는 "터미널"의 개념이 있다고 (100 % 확신하지는 않는다) 생각하지 않습니다. 내가 아는 한 모든 솔루션은 적어도 플랫폼 특정 동작에 의존해야합니다. – hyde

3

코드 페이지를 러시아어 또는 특정 언어로 변경하는 것보다 유니 코드를 사용하는 것이 좋습니다. Windows API는 UTF16을 사용합니다. 불행하게도 Windows 콘솔에는 유니 코드 지원이 제한되어 있습니다. 다음은 Windows 콘솔 및 Visual Studio 전용 솔루션입니다 (예를 들어 MinGW에서는 작동하지 않음). 당신은 UTF16으로 모드를 변경 한 후 std::cinstd::cout을 사용할 수 없습니다

#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; 
} 

참고 아직 일부 아시아 언어에서 작동하지 않습니다 (또는 적어도 나는 그것을 작동하게하는 방법을 모른다). ANSI 입/출력을 계속 사용하려면 모드를 _O_TEXT으로 다시 설정해야합니다. 예 :

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

UTF16에 입력을 수신 한 후에는 네트워크 기능 등과의 호환성을 위해 (char에 저장되어있는) UTF8로 변환 WideCharToMultiByte(CP_UTF8, ...)을 사용할 수 있습니다

내 주요 문제가 있었다
1

, I didn 히 있음 처음에는 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; 
} 

감사합니다.