콘솔 게임에 쓰기 위한 입력함수


건방진 네이밍 stdInput

--------------------------------------------------------------------

1~9숫자키, ENTER 키를 버퍼, 에코 없이 입력가능하게 하라

영어 문장은 버퍼를 쓰는데 "skip", "SKIP", "gg", "GG", "menu", "MENU" 빼고는 받지 않는다.

--------------------------------------------------------------------

문제점 1)그런데 어떤 짓을 하면 함수가 값을 반환하지 않는다. 근데 이유도 모르겠고 어떤 기준인지도 모르겠군여

문제점 2)엔터키는 왜 13이 아니라 3으로 출력되는거지?

문제점 3)가끔씩 예외가 아닌 영단어(예 gg)를 넣어도 0을 반환한다. - 이건 문제가 큰데...

문제점 4)strncmp가 이유는 모르겠지만 작동을 안해서 걍 내가 하나 만들어 썼는데, 뭐 이건 상관 없으려나...


뭔가 상당히 불안정하다 으아

실행파일도 txt로 첨부.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#include <stdio.h>
#include <conio.h>
#include <string.h>
 
#define INPUT_STR_LEN_MAX    10
 
enum strCommand{
    sKIP    =    1000,
    SKIP,
    mENU    =    2000,
    MENU,
    gG        =    3000,
    GG,
};
 
enum fnKey{
    ARROW_START    =    -32,
    UP            =    72,
    DOWN        =    80,
    RIGHT        =    77,
    LEFT        =    75,
    ENTER        =    13,
};
 
int areSameStr(char* str, char* cmp, int count);
void clearLine_readBuffer();
int stdInput();
 
int main(){
    
    while(1){
        int a = stdInput();
        printf("%d / %c \n", a, a );
    }
 
    return 0;
}
 
// \n이 읽혀질 때 까지 입력버퍼에 저장된 문자를 지우는 함수
void clearLine_readBuffer()
{
    while( getchar() != '\n');
    //버퍼가 빈 경우에는 쓰면 안된다.
}
 
 
//사용자의 입력을 처음 받아 가공하는 함수. 문자열로 입력을 받으며 온갅 예외처리를 한다.
int stdInput()
{
    char firstCh = 0;
 
    firstCh = _getch();
    if( firstCh == ARROW_START){    //방향키                            
        firstCh = _getch();
 
        switch(firstCh){
            case UP:
            case DOWN:
            case RIGHT:
            case LEFT:
                return firstCh;
        }
        return 0;
    }
    else if( firstCh == ENTER  ||  (firstCh >= '1' && firstCh <= '9') ){    //엔터, 숫자키
        return firstCh;
    }
    else if(  (firstCh >= 'A' && firstCh <= 'Z')  ||  ( firstCh >= 'a' && firstCh <= 'z') ) {//알파벳 대문자 || 소문자
        char* endChecker = NULL;
        int strLen;
        char str[INPUT_STR_LEN_MAX];    //문자열 커맨드 입력을 위한 버퍼
        char firstStr[2 + INPUT_STR_LEN_MAX] ={ firstCh, '\0' };    //str을 여기에 붙이므로 검사에 이걸 쓴다.
 
        _putch(firstCh);
 
        endChecker = fgets(str, sizeof(str), stdin);
 
        strLen = 0;
        while(*endChecker != '\0'){
            strLen++;
            endChecker++;
        }
        if(strLen >= INPUT_STR_LEN_MAX){//버퍼에 사용자가 입력한 값이 남을 때만
            clearLine_readBuffer();
            //입력한 문자열 배열의 길이가 \n 포함해서 (INPUT_STR_LEN_MAX1) 이상이면 사용한다.
            //(INPUT_STR_LEN_MAX1)-2 이하부터는 입력을 한번 더 받기 때문에 어색하다.
        }
 
        strcat(firstStr, str);
 
        if( areSameStr(firstStr,"skip\n"6) ){
            return sKIP;
        }else if( areSameStr(firstStr,"SKIP\n"6) ){
            return SKIP;
        }else if( areSameStr(firstStr,"menu\n"6) ){
            return mENU;
        }else if( areSameStr(firstStr,"MENU\n"6) ){
            return MENU;
        }else if( areSameStr(firstStr,"gg\n"4) ){
            return gG;
        }else if( areSameStr(firstStr,"GG\n"4) ){
            return GG;
        }else{
            clearLine_readBuffer();
            return 0;
        }
    }
}
 
int areSameStr(char* str, char* cmp, int count)
{
    int result = 0;
    int i;
 
    for(i = 0; i < count; i++){
        if( str[i] != cmp[i] ){
            return 0;
        }
    }
 
    return 1;
}
 
 
cs