0

矢印キーを使用してワイド文字に変換できるかどうかを判断しようとしています。私はその getch() 関数に conio.h を使用しています。同様の関数と比較してどのように機能するかが好きで、矢印キーを取得するには 2 回呼び出す必要があります。

矢印キーを押すと、最初の文字として 0xE0 (-32) が返され、{左 = 'K'、上 = 'H'、右 = 'M'、下 = 'P'} になります。

だから私は2つのキャラクターを1つにマージする方法を見つけようとしています. これは私が思いついた最も近いものです。ただし、ファンクション キーは機能しません。ファンクション キーを押しても、常に同じ値が返されます。{F1-12 = 0, Arrows = 224} 信頼できる Windows 電卓を取り出して、224 が 2 進数の -32 に相当することを確認できました。私はそれをバイトに落とし、10進法を使用し、100 + 124になり、= -32でした。

したがって、変換が配列の最初の文字のみを考慮している理由を誰かが理解するのを手伝ってくれるかもしれません。私は確かに何か悪いことをしました。話はもう十分です。そうであれば、長くなりすぎて申し訳ありません。コードは次のとおりです。

#include <iostream>
#include <stdio.h>
#include <windows.h>
#include <wincon.h>
#include <conio.h>
#include <cwchar>

/**int main()
{
    int N;
    char C;
    wchar_t R;

    while(true)
    {
        while(!kbhit()){}
        //C = getch();

        //if((R == 0) || (R == 224))

        std::cout << R << std::endl;
        N = R;
        std::cout << R << " = " << N << std::endl;
    }
}*/



int main()
{
    int N = 0;
    char C[2];
    wchar_t R;
    mbstate_t mbst;

    while(true)
    {
        mbrlen(NULL,0,&mbst);
        memset(&mbst,0,sizeof(mbst));

        for(int i = 0; i < 2; ++i)
        {
            while(!kbhit()){}
            C[i] = getch();
            N = C[i];
            switch(N)
            {
                case 0:
                    break;
                case -32:
                    break;
                default:
                    //input needs to be converted
                    mbrtowc(&R,C,2,&mbst);
                    N = R;
                    std::cout << R << " = " << N << std::endl;
                    i = 3;
                    break;
            }
        }
    }
}

編集:

ユニオンを使用して 2 バイトを結合する方法を見つけました。これを投稿した時点では、労働組合が何であるかを知りませんでした。ユニオンにより、2 つの異なるデータ型に同じメモリ空間を使用できます。仕組みはこちら - http://www.cplusplus.com/doc/tutorial/other_data_types/

4

1 に答える 1

0

私は自分の問題を解決することができましたが、私が試みていた方法では解決できませんでした. 誰かが私が間違っていたことを理解するのを手伝いたいなら、それは素晴らしいことです.

ただし、すべてのキーを一意の 2 バイト変数として読み取る限り、回避策を作成できました。ビットのシフトに関する質問を見つけ、それを使用して 2 つの文字を結合しました。その後、数字が適切に結合されていないことがわかりました。これは、unsigned char の代わりに signed char を使用していたためであることがわかりました。unsigned char を使いたくなかったので、union を使った新しい解決策を見つけました。

これが私のユニオンソリューションです。とてもシンプルです。

#include <iostream>
#include <conio.h> //getch() & kbhit()
#include "rndgen.h"
#define FN_ESCAPE 27
#define FN_UP_ARROW 18656
#define FN_DOWN_ARROW 20704
#define FN_LEFT_ARROW 19424
#define FN_RIGHT_ARROW 19936
                                                                    //This union allows for two 8-bit values to be read as one 16-bit value 
union wide_char
{
    short wide_C;
    char C[2];
};
                                                                    //Function waits for a key to be pressed
inline short key_wait()
{
    wchar_t R;
    wide_char user_input;
    user_input.wide_C = 0;
                                                    //Loop twice, or until code causes the loop to exit
                                                        //Two times are neccessary for function keys unfortunately
    for(int i = 0; i < 2; ++i)
    {
                                                //While there isn't a key pressed, loop doing nothing
        while(!kbhit()){}
                                                //Grab the next key from the buffer
                                                    //Since the loop is done, there must be at least one
        user_input.C[i] = getch();
        switch(user_input.C[i])
        {
            case 0:
            case -32:
                                                //The key pressed is a Function key because it matches one of these two cases
                                                    //This means getch() must be called twice
                                                    //Break switch, run the for loop again ++i
                break;
            default:
                R = user_input.wide_C;
                return R;
                break;
        }
    }
    return -1;
}

wide_C は、C[2] のビットをこの順序 {C[1],C[0]} で返します。これは、F1-12 を一意に読み取ることができることを意味するため、これは素晴らしいことです (F1-12 の最初の文字の戻り値は 0 です)。おそらく短いものを wchar_t に置き換えることもできますが、壊れていないものを修正する理由がわかりました。別のプログラムの新しいソリューションでコードを再実装することにした場合は、そうするかもしれません。

これはまた、aZ & 0-9 はすべて通常の char 値として読み取ることができることを意味します。

于 2013-10-23T11:18:54.540 に答える