2012-03-31 18 views
2

このサイトでは、約30分読み込まれています。Console.ReadKey()メソッドとConsoleKeyInfo変数を使用して、拡張ASCII文字を正しいプレゼンテーションに変換します。

次のことを仮定し、C#のコンソールアプリケーションで:

ConsoleKeyInfo cki; 
cki = Console.ReadKey(true); 
Console.WriteLine(cki.KeyChar.ToString()); //Or Console.WriteLine(cki.KeyChar) as well 
Console.ReadKey(true); 

、のは、コンソールエントリに¿を入れ、Console.ReadKey(true)経由ckiにそれをasignてみましょう。表示されるのは¿シンボルではなく、¨シンボルが代わりに表示されます。そして他の多くのキャラクターでも同じことが起こります。例:ñ¤¡-´ïを示します。

それでは、同じコードsnippletを取ると行動のようなよりConsole.ReadLine()のためのいくつかのものを追加してみましょう。

string data = string.Empty; 
ConsoleKeyInfo cki; 
for (int i = 0; i < 10; i++) 
{ 
    cki = Console.ReadKey(true); 
    data += cki.KeyChar; 
} 
Console.WriteLine(data); 
Console.ReadKey(true); 

正しい方法でこれを処理する方法の質問に、あるべき右の文字を印刷終了¨¤-ïなどのようなものではなく、dataに保存されていますか?

ConsoleKeyInfoConsole.ReadKey()で動作するソリューションが必要です。他の変数タイプや読み取りメソッドは使用しないでください。

EDIT:

ReadKey()メソッドは、そのコンソールの名前空間から来て、Kernel32.dllのそれdefinetively悪いハンドル拡張ASCIIとUnicodeに依存するので、それはもはや選択肢ではないだけのための有効な変換を見つけるにそれは何を返します。

ReadKey()の不正な動作を処理する有効な唯一の方法は、cki = Console.ReadKey(true)で書かれたcki.Keyプロパティを使用してスイッチを適用し、次にどのキーが押されたかの依存性について正しい値を返すことです。

は、例えば、ハンドルにÑキーを押し:

string data = string.Empty; 
ConsoleKeyInfo cki; 
cki = Console.ReadKey(true); 
switch (cki.Key) 
{ 
    case ConsoleKey.Oem3: 
     if (cki.Modifiers.ToString().Contains("Shift")) //Could added handlers for Alt and Control, but not putted in here to keep the code small and simple 
      data += "Ñ"; 
     else 
      data += "ñ"; 
     break; 
} 
Console.WriteLine(data); 
Console.ReadKey(true); 

だから、今の質問は、他の機能は、それが押された1つのキーだけで実行だ完了し、より広いフォーカスを...持っている、と押されているものを返します( ReadKey()の代替)?私はそのような代用品はないと思うが、確認された答えが役に立つだろう。

+0

Mmm ...よく、これから1つの質問が私の頭に浮かんでいます...なぜConsole.ReadLine()メソッドがそれを区別するのですか?それはñ、¿、 'のような正しい文字を取得し、正しい方法で文字列や文字に変換します。マイクロソフトがメソッドのソースコードをリリースすれば、より簡単になります。D – mishamosher

+1

さて、彼らはそうしました。 http://referencesource.microsoft.com/netframework.aspx –

+0

ユニコードをサポートしていないコンソールについては、私は確信していません... 2つの速い結果は反対です:http://stackoverflow.com/questions/1259084/what- encoding-code-page-is-cmd-exe-usingとhttp://www.perlmonks.org/?node_id=329433 – mishamosher

答えて

0

ReadLine()は、拡張ASCIIおよびUnicode文字を正しく使用するようにコードページを再設定します。 ReadKey()はEN-USのデフォルト(コードページ850)になります。

あなたが望む文字を印刷するコードページを使用すれば、それだけです。そのうちのいくつかのためにhttp://en.wikipedia.org/wiki/Code_pageを参照してください:)

をので、Ñキーを押しために、解決策はこれです:

Console.OutputEncoding = Encoding.GetEncoding(1252); //Also 28591 is valid for `Ñ` key, and others too 
string data = string.Empty; 
ConsoleKeyInfo cki; 
cki = Console.ReadKey(true); 
data += cki.KeyChar; 
Console.WriteLine(data); 
Console.ReadKey(true); 

シンプル:)

そして、サイドノート:いくつかのケースでは、それはまたですConsole.InputEncodingプロパティを再設定する必要があります。

また、コンソール(Lucida Console/Consolas)に別のフォントを選択すると、この問題が発生することに注意してください。 Lottaはこれに対してユーザーAbelに感謝し、彼は解決のためにフォントを変更するように任命し、これがfalseであることを発見しました。

+0

これはおそらく、単一のキー入力としてñを持つスペイン語キーボードでのみ機能します。他のキーボードで '〜' + 'n'やAlt + Numの組み合わせを入力する必要はありません。また、Unicodeの大部分を占めるWindows-1252以外の文字でも機能しません。あなたがユニコード以外のソリューションを選んだのはわかりませんが、これはコンソール上のスペイン語キーボードで動作する唯一のものです。残念ながら、それはあなたを非常に制限し、幅広い顧客にソリューションを出荷することを困難にしています。 – Abel

+0

良い点、いいえ、Alt + Num項目は処理されません。そして、私はこれを繰り返します。これは '' ''と '' i''のようなコンボキーで動作し、他の多くのもの、actiollyでは、押された最初のキーが直ちに表示されないコンボで動作します( 'ほとんどの場合、 '' ''、 ''など) – mishamosher

+0

なぜ私はユニコード以外のソリューションを選んだのですか?それはちょうど2つのことです:本当に古いオペレーティングシステムとの相互運用性、そして私はC#空き時間がありません。これは検証のためだけであり、英語やスペイン語のエントリは何もありません。それは単に大学の目的にすぎないことを覚えておいてください。私はTo-Be-Sold製品の場合、最初からWinFormsを選択する – mishamosher

1

問題は、コンソールがUnicodeを処理する方法を知らないということではありません(正しく、check out this thread)。問題は、キーボードのキー入力、キーコードへの変換、キーコードの文字への変換、およびReadKey()メソッドの動作の理解にあります。

まず、連続した文字を読みたい場合は、代わりにConsole.ReadLine()を使用してください。

はのは、次のプログラムを見てみましょう:

Console.WriteLine("Press a key to start (Enter to stop)."); 

var key = Console.ReadKey(); 
var allKeys = ""; 

while(key.Key != ConsoleKey.Enter) 
{ 
    Console.WriteLine(key.KeyChar); 
    allKeys += key.KeyChar; 
    key = Console.ReadKey(); 
} 

それは、文字列に付加するよりも、入力から鍵を読み出します。心配するものはありません。違う!あなたがこれを行うことができ、米国の国際キーボードで:

  • タイプ `+ aがà
  • タイプAltキー+ 123は{
  • タイプはAlt + 3355は←
  • タイプとなっなっなりました。スペイン語キーボードの場合と同様に、ñ

に応じて、特定の文字に対して異なるキーを押します。時には鍵の組み合わせを打つこともあります。上記の最初の組み合わせは、\0aという文字列とキーコード0(列挙型ではない)、次にConsoleKey.Aと記録されています。結果の文字列の合計は"\0á{←ñ"になりました。

Alt + 123/3355は、キーコード18(これはAltキー)として記録されています。数字キーの文字への変換は、コンソールに送信される前にOSによって実行されます。スペイン語キーボードのUSキーボードまたはñ;を入力

はあなたにConsoleKey.Oem1(US)とConsoleKey.Oem3(スペイン)が表示されます。

私はあなたの行動を模倣することはできませんが、これはおそらくあなたの画面がないためですが、コンソールフォントとして持っているフォントは非Unicode文字をサポートしていないようです。 Windows 7では、デフォルトでは、他のWindowsバージョンについてはわかりません。また、コンソールのコードページが正しく設定されていない可能性もあります。コンソールにと(それがIMEで悪化したキーの組み合わせが許可されているかどうかを国際設定でキーボードを選択し、文字がキーボードのレイアウトに依存して構成するもの
をまとめ、選択した言語、選択したコードページに

!)。 KeyCharから通常のcharに移行するのは簡単ではありませんが、システム設定が互いに同期しているかどうかによって異なります。

私のシステムであなたのサンプルを実行すると、私は同じ動作をしません。しかし、もう一度、私はあなたのシステムを持っていません。

キーからキャラクターへの移行は難しいビジネスです。私はあなたが自分の能力をシステムに既に存在するものを改革することに頼っていないことをお勧めします。何が起こっているのかを見てみるのは良い習慣ですが、実際はReadLine;に戻ってください)。

編集:
最新の編集を見ました。入力と出力には異なるエンコーディングを使用できます(Console.InputEncodingConsole.OutputEncoding)。 Unicodeに切り替えると、コードページはもはや重要ではないことを強調するために、他のスレッドを引用したいと思います。これは、最近のWindowsバージョンのデフォルトの動作です:

あなたは、このようなルシーダコンソールやConsolasなどのUnicodeフォントを選択した場合、その後、あなたが見ると、コンソール上でUnicode文字を入力することができるようになります 、 に関係なくどのようなchcpは:

+0

さらに多くの礼儀作法と感謝のためにちょうど2つのことがあります。私はMicrosoftから直接ソースを扱い、それに逆コンパイルを適用したので、ReadKey(Console.cs)を持つ.CSファイルを取得しました。私はdissememlingで違法な操作を行ったことを知っていますが、文書化されています。 ReadKeyは、キャプチャした内容をWin32Native.InputRecord変数に格納し、ReadLineはStringBuilderでこれを行い、そのうちの1つはデフォルトのコードページを使用し、もう1つはシステムコードを使用します。ちなみに、私はWindows 7、スペイン語LAにいます。 – mishamosher

+0

システムが持つキーボードレイアウトに基づいて、適切なエンコーディングを使用するだけです。私はReadLineに戻っていません。なぜなら、何が押されたかにかかわらず、キーが押されたときに終了するものがほしいからです。これを行うことがわかっている唯一のものはReadKeyです。そして、...余分なacarationsバディに感謝:)。 – mishamosher

+0

@mishamosher:どうぞよろしくお願いします。エンコードについてはあなたが正しいです(私の編集を見てください)。それでも、 '〜'と 'n' ='ñ'の組み合わせキーを処理しなければならないことを知っておくことが重要です。あなたが持っているコードページにかかわらず、それらを直接格納すると、断続的な '\ 0'をあなたの文字列に格納し、あなたがそれを望んでいないと確信しています。エンコードに関するもう1つのこと:フォントがUnicode(Raster FontまたはLucida Sansを選択)をサポートする場合、入力と出力の両方がサポートされており、エンコーディングを指定する必要はありません。さらに、255文字に制限されず、Unicode全体の範囲に制限されています。 – Abel

関連する問題