(How to read arrow keys) Cheat code in C programming (when inputted from the keyboard)

风流意气都作罢 提交于 2020-01-14 06:52:09

问题


I am making a game in C, and when the user input the Konami code (cheat code), the program should print out the correct answer. (edit #3) found out that my program does not "read" the arrow keys whenever I input it, how do I make it so? pls. see my comment below

Here is my updated code (edit #2): //try konami

#include<stdio.h>
#include<string.h>

main() {

    int c;
    char cheat[] = {24,24,25,25,27,26,27,26,98,97}; //thanks to Vicky for clarifying this
    char guess[100];

    printf("Enter guess: "); 
    scanf("%c", &guess);

    //just checking if the cheat array is right, and yes it is. I'll remove this later
    for ( c = 0; c < 11; c++ ) {
        printf("%c", cheat[c]);
    }


    //comparison of the guess (input) to the cheat code
    if (strcmp (cheat, guess) == 0  )
       printf("\nYou win!");
    else
       printf("\nLol!");

}

Now, my problem is it always prints Lol! even though I input the cheat code correctly . . .

note: this is for my intro class in programming (my first time in c too). lessons covered so far are basics, loops, arrays and strings (no functions yet but i understood that now, no structures and further pls. thank you :)


回答1:


my question is how do i check it coming from the user

I'm hearing that you want to know when the user presses an arrow key? I had to do this in C++ and it turned out to be a very enlightening experience, so although you are using C and not C++ i will still share what i remember.

Arrow keys take a sequence of bytes instead of one AND are usually implemented at the hardware level!

Though whatever operating system you are using should have support (goodbye portability), the term you need to be looking for is key codes and in windows they call them Virtual-Key Codes

On Windows I had learn to program with the win32api.

I can easily show you the key codes for windows (and i will paste them from that link) but they are no good to you unless you want to commit to a windows event driven type program (maybe you already are?), these codes are fetched from the key events in your program and are not ascii-codes and i would go as far to assume specific to windows.

VK_LEFT
0x25
LEFT ARROW key
VK_UP
0x26
UP ARROW key
VK_RIGHT
0x27
RIGHT ARROW key
VK_DOWN
0x28

And in linux I still had to deal with events, this time using X11, oh the joys i had with X11! the keycodes here are called XK_[key] i.e XK_left.

These key codes are defined in the header <X11/keysymdef.h> - Xlib programming manual

see header online

#define XK_Left                          0xff51  /* Move left, left arrow */
#define XK_Up                            0xff52  /* Move up, up arrow */
#define XK_Right                         0xff53  /* Move right, right arrow */
#define XK_Down                          0xff54  /* Move down, down arrow */

Hopefully this can set you on the right path, whenever i need arrow keys now i just use wasd.


EDIT: This is the windows one, i condensed it down from the C++ game i made to this C program,it's a lot of code, anything that looks like it shouldn't be there probably shouldn't, but it compiles and reads the arrow keys, so everything you need is in this source atleast.

WINDOWS;

#include <stdlib.h>
#include <stdio.h>
#include <Windows.h>
#include <Tchar.h>

        //directional keys
#define key_left  0x25
#define key_up  0x26
#define key_right  0x27
#define key_down  0x28

        // to quit
#define key_escape  0x1B


char checkType(INPUT_RECORD *buffer, int i);
int checkKey(INPUT_RECORD *buffer, int i);
void outputString(const char *str, SHORT col, SHORT row);
void outputChar(char ch, SHORT col, SHORT row);
void clearScreen(void);

CHAR_INFO *p_consoleBuffer;


HANDLE whnd;    // handle to write console
HANDLE rhnd;    // handle to read console


SMALL_RECT winSize;
COORD buffSize;

SHORT consoleHeight = 25;
SHORT consoleWidth = 60;

DWORD Events = 0; // Event count
DWORD EventsRead = 0; // Events read from console



int _tmain(int argc, _TCHAR* argv[]){

    // set up handles for read/writing:
    whnd = GetStdHandle(STD_OUTPUT_HANDLE);
    rhnd = GetStdHandle(STD_INPUT_HANDLE);

    SetConsoleTitle(TEXT("DEMO WIN PROG"));

    SMALL_RECT winLen = {0,0,((SHORT)consoleWidth-1),((SHORT)consoleHeight-1)};

    COORD bLen = {consoleWidth,consoleHeight}; // width / height
    winSize = winLen;

    // set console size
    SetConsoleWindowInfo(whnd, TRUE, &winSize);

    // set the buffer size coords
    SetConsoleScreenBufferSize(whnd, buffSize);

    CHAR_INFO consoleBuffer[consoleHeight*consoleWidth];
    p_consoleBuffer = consoleBuffer;

    CONSOLE_CURSOR_INFO cci;
    cci.dwSize = 1;
    cci.bVisible = FALSE;
    SetConsoleCursorInfo(whnd, &cci);

    clearScreen();

    int Running = 1;
    char type = 0;

    while(Running) {
        //game loop

        GetNumberOfConsoleInputEvents(rhnd, &Events);

        if(Events != 0){ // something happened

            // create buffer the size of how many Events & store
            INPUT_RECORD eventBuffer[Events];
            // fills buffer with events and save count in EventsRead
            ReadConsoleInput(rhnd, eventBuffer, Events, &EventsRead);


            DWORD i;
            for(i = 0; i<EventsRead; ++i){
                type = checkType(eventBuffer,i);

                if(type == 'k'){ // event type was key

                    int key = checkKey(eventBuffer, i);
                    int arrow_key_pressed = FALSE;

                    switch (key){
                        case key_up:
                        case key_down:
                        case key_left:
                        case key_right:
                            // IF ANY ARROW KEY WAS PRESSED, EXECUTION WILL "COLLAPSE" TO HERE
                            arrow_key_pressed = TRUE;
                            break;

                        case key_escape:
                            // escape was pressed
                            Running = 0;
                            break;

                        default:
                            // no case was pressed
                            break;
                    }


                    clearScreen();
                    if(arrow_key_pressed){
                        const char *str = "Arrow key was pressed";
                        outputString(str, 20, 12); // roughly centre
                    }else {
                        const char *str = "Arrow key was not pressed";
                        outputString(str, 20, 12);
                    }


                }else if(type == 'm'){
                    // MOUSE CLICK, I'M NOT COVERING SORRY.
                }
            }
        }
    }
    return 0;
}

char checkType(INPUT_RECORD *buffer, int i){
    if(buffer[i].EventType == MOUSE_EVENT){
        return ('m');
    }else if(buffer[i].EventType == KEY_EVENT){
        return ('k');
    }else return (0);
}

int checkKey(INPUT_RECORD *buffer, int i){
    return (buffer[i].Event.KeyEvent.wVirtualKeyCode);
}

void outputString(const char *str, SHORT col, SHORT row){
    SHORT fs_len = strlen(str);
    int i;
    for(i = 0; i<fs_len; ++i){
        outputChar(str[i], col++, row);
    }
}

void outputChar(char ch, SHORT col, SHORT row){
    p_consoleBuffer[row*consoleWidth+col].Char.AsciiChar = ch;
    p_consoleBuffer[row*consoleWidth+col].Attributes = 240;

    SHORT CH = consoleHeight, CW = consoleWidth;
    COORD charBufSize = {CW,CH};
    COORD charPos = {0,0};
    SMALL_RECT writeArea = {0,0,CW,CH};
    WriteConsoleOutputA(whnd,p_consoleBuffer,charBufSize,charPos,&writeArea);
}

void clearScreen(void){
    int i;
    for(i = 0; i<(consoleHeight*consoleWidth); ++i){
        //fill it with white-backgrounded spaces
        p_consoleBuffer[i].Char.AsciiChar = ' ';
        p_consoleBuffer[i].Attributes =
            BACKGROUND_BLUE |
            BACKGROUND_GREEN |
            BACKGROUND_RED |
            BACKGROUND_INTENSITY;
    }

    // clear screen
    SHORT CH = consoleHeight, CW = consoleWidth;
    COORD charBufSize = {CW,CH};
    COORD charPos = {0,0};
    SMALL_RECT writeArea = {0,0,CW,CH};
    WriteConsoleOutputA(whnd,p_consoleBuffer,charBufSize,charPos,&writeArea);

}

/* Remember i did this in c++, i made a class with these ints
   to represent the virtual key codes, you can define them how you
   want like i did or use windows actual definitions.

        //special keys
        key_escape = 0x1B;
        key_space = 0x20;
        key_home = 0x24;
        key_end = 0x23;
        key_pgUp = 0x21;
        key_pgDown = 0x22;
        key_caps = 0x13;
        key_shift = 0x10;
        key_ctrl = 0x11;
        key_backspace = 0x08;
        key_tab = 0x09;
        key_enter = 0x0D;
        key_alt = 0x12;
        key_delete = 0x2E;

        //directional keys
        key_left = 0x25;
        key_up = 0x26;
        key_right = 0x27;
        key_down = 0x28;

        //number keys
        key_0 = 0x30;
        key_1 = 0x31;
        key_2 = 0x32;
        key_3 = 0x33;
        key_4 = 0x34;
        key_5 = 0x35;
        key_6 = 0x36;
        key_7 = 0x37;
        key_8 = 0x38;
        key_9 = 0x39;

        // alphabet keys
        key_a = 0x41;
        key_b = 0x42;
        key_c = 0x43;
        key_d = 0x44;
        key_e = 0x45;
        key_f = 0x46;
        key_g = 0x47;
        key_h = 0x48;
        key_i = 0x49;
        key_j = 0x4A;
        key_k = 0x4B;
        key_l = 0x4C;
        key_m = 0x4D;
        key_n = 0x4E;
        key_o = 0x4F;
        key_p = 0x50;
        key_q = 0x51;
        key_r = 0x52;
        key_s = 0x53;
        key_t = 0x54;
        key_u = 0x55;
        key_v = 0x56;
        key_w = 0x57;
        key_x = 0x58;
        key_y = 0x59;
        key_z = 0x5A;
*/

LINUX: (X11) This is that example program i used, it was actually when i first started programming that i wanted to do this myself, and i cannot remember where it came from or who wrote it, so i cannot credit them unfortunately, but here is the source;

#include <stdio.h>
#include <stdlib.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xos.h>
#include <X11/Xatom.h>
#include <X11/keysym.h>
/*Linux users will need to add -ldl to the Makefile to compile
 *this example.
 */
Display *dis;
Window win;
XEvent report;
GC green_gc;
XColor green_col;
Colormap colormap;
/*
Try changing the green[] = below to a different color.
The color can also be from /usr/X11R6/lib/X11/rgb.txt, such as RoyalBlue4.
A # (number sign) is only needed when using hexadecimal colors.
*/
char green[] = "#00FF00";

int main() {
        dis = XOpenDisplay(NULL);
        win = XCreateSimpleWindow(dis, RootWindow(dis, 0), 1, 1, 500, 500, 0, BlackPixel (dis, 0), BlackPixel(dis, 0));
        XMapWindow(dis, win);
        colormap = DefaultColormap(dis, 0);
        green_gc = XCreateGC(dis, win, 0, 0);
        XParseColor(dis, colormap, green, &green_col);
        XAllocColor(dis, colormap, &green_col);
        XSetForeground(dis, green_gc, green_col.pixel);

        XSelectInput(dis, win, ExposureMask | KeyPressMask | ButtonPressMask);

        XDrawRectangle(dis, win, green_gc, 1, 1, 497, 497);
        XDrawRectangle(dis, win, green_gc, 50, 50, 398, 398);
        XFlush(dis);

        while (1)  {
        XNextEvent(dis, &report);
        switch  (report.type) {
            case Expose:
                fprintf(stdout, "I have been exposed.\n");
                                XDrawRectangle(dis, win, green_gc, 1, 1, 497, 497);
                                XDrawRectangle(dis, win, green_gc, 50, 50, 398, 398);
                                XFlush(dis);
                        break;
            case KeyPress:
            /*Close the program if q is pressed.*/
                    if (XLookupKeysym(&report.xkey, 0) == XK_q) {
                        exit(0);
                    }
                    break;
                }
        }

        return 0;
}


来源:https://stackoverflow.com/questions/21408837/how-to-read-arrow-keys-cheat-code-in-c-programming-when-inputted-from-the-key

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!