web-dev-qa-db-ja.com

C ++コンソールでキリル文字を書く方法

たとえば、私が書く場合:

cout << "Привет!" << endl; //it's hello in Russian

コンソールでは、╧ЁштхЄ!のようになります。

OK、私たちは使用できることを知っています:

setlocale(LC_ALL, "Russian");

しかし、その後、ロシア語のコマンドライン引数は機能しません(BATファイルからプログラムを開始した場合)。

StartProgram.bat

chcp 1251
MyProgram.exe -user=Олег -password=Пароль

したがって、setlocaleの後、プログラムはロシア語の引数を正しく読み取ることができません。

これは、CP1251のBATファイルが、コンソールがCP866にあるために発生します。

だから、質問があります:

C++コンソールでロシア語のテキストを記述し、同時にロシア語のコマンドライン引数を正しく読み取るにはどうすればよいですか。

15
VextoR

MichaelKaplanのブログから次のエントリを参照してください。

http://www.siao2.com/2008/03/18/8306597.aspx

7

wcoutを使ってみましたか? coutに似ていますが、「ワイド」文字を受け入れるため、適切なユニコードエンコーディングが可能です。

この ローカリゼーションに関する記事 および 別の 、どちらもMSD​​Nからのものである可能性があります。

6
e.James

コンソールは866ではなく1251に設定されています:

 //Save As Windows 1251
    #include<stdio.h>
    #include<windows.h>
    int main(int argc, char **argv){ 
        SetConsoleOutputCP(1251);
        SetConsoleCP(1251);
        if(argc<2)return 0;
        else printf("Hello %s %s\n",argv[1],argv[2]);
    } 

プログラムはargument.exeであり、結果は次のとおりです。

D:\ Debug>引数ОлегПароль
こんにちはОлегПароль

2
vladasimovic

コントロールパネルの[地域と言語のオプション]セクションで、非Unicodeプログラムの言語をロシア語に設定しましたか?

(ロシア語を話すプログラマーの通常の設定がどのようなものかわかりません。過度に偏狭なツールを混乱させないように、これをある種の英語に設定するのが一般的かどうか疑問に思います。)

私の記憶が悪戯をしているのでない限り、日本の開発者からのコードを扱っていたとき、コンソールに非Unicode日本語テキスト(Shift-JISエンコーディング)が正しく表示されるようになったのはこのステップでした。

1

次の関数を使用してみてください setlocale() および SetConsoleOutputCP()

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

WriteConsoleWはUNICODEを処理できます。問題のないキリル文字。 wcoutのフォーマット機能を見逃さない場合は、標準のwcoutストリームバッファーをリダイレクトして、WriteConsoleW

完全な例をここに示します

// save and redirect cout buffer
wostringstream  newCoutBuffer;
wstreambuf*     oldCoutBuffer = wcout.rdbuf(newCoutBuffer.rdbuf());    

// do your wcout stuff here
// do your wcout stuff here

DWORD dwWritten;
WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), newCoutBuffer.str().c_str(),newCoutBuffer.tellp(),&dwWritten,NULL);  

// restore cout buffer
wcout.rdbuf(oldCoutBuffer);
0
seizu

私にとって、これは問題を解決するようです:

#include <fcntl.h>
#include <io.h>
#include <iostream>

using namespace std;

int main(void) {
    _setmode(_fileno(stdout), _O_U16TEXT);
    wcout << L"Огњен" << endl;
    return 0;
}

最も正しい方法は、wcout + std :: imbueを使用することです。

ただし、Windows Vista/7で発生したsetlocaleAPIにいくつかの変更があったことを知っておく必要があります。 「ロシア語」ロケール文字列は、少なくともVisual C++ CRTでは、「cp866」として認識されなくなりました。

Cp866出力を取得するには、代わりにこれを使用してみてください。

::setlocale( LC_ALL , "russian_russia.866" );
0
Yury Rumega