2016-11-03 7 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コンソールのUnicodeサポートは制限されています。ここでは、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

私の主な問題は、私は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; 
} 

ありがとうございました。

関連する問題