たとえば、私が書く場合:
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++コンソールでロシア語のテキストを記述し、同時にロシア語のコマンドライン引数を正しく読み取るにはどうすればよいですか。
MichaelKaplanのブログから次のエントリを参照してください。
wcout
を使ってみましたか? cout
に似ていますが、「ワイド」文字を受け入れるため、適切なユニコードエンコーディングが可能です。
この ローカリゼーションに関する記事 および 別の 、どちらもMSDNからのものである可能性があります。
コンソールは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>引数ОлегПароль
こんにちはОлегПароль
コントロールパネルの[地域と言語のオプション]セクションで、非Unicodeプログラムの言語をロシア語に設定しましたか?
(ロシア語を話すプログラマーの通常の設定がどのようなものかわかりません。過度に偏狭なツールを混乱させないように、これをある種の英語に設定するのが一般的かどうか疑問に思います。)
私の記憶が悪戯をしているのでない限り、日本の開発者からのコードを扱っていたとき、コンソールに非Unicode日本語テキスト(Shift-JISエンコーディング)が正しく表示されるようになったのはこのステップでした。
次の関数を使用してみてください setlocale()
および SetConsoleOutputCP()
setlocale(LC_ALL, "Russian");
SetConsoleOutputCP(866);
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);
私にとって、これは問題を解決するようです:
#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" );