본문 바로가기
프로그래밍 언어/C, C++ 다양한 예시들

[C/C++] 메뉴 선택 방식

by Physics 2021. 8. 24.
728x90

목적 

1. 사용자가 프로그램의 특정한 선택 사항 중 하나를 선택하도록 함
2. 가능한 문제점 
  - 사용자가 프로그램의 지시대로 따를 때, 프로그램이 부드럽게 넘어가도록 만드는 것 
  - 사용자가 지시대로 따르지 않을 때에도 프로그램이 부드럽게 넘어가게 하는 것 

Pseudo code

1. 선택을 얻는다. 
2. 그 선택이 'q'가 아닌 동안 
    - 원하는 선택으로 이동하여 지정된 작업을 수행 
    - 다음 선택을 얻음 

NOTE 1: 메뉴를 반복적으로 접근하도록 하기 위해, while 문을 이용
NOTE 2: 수행할 작업들은 switch-case 문으로 해결 

 

예시 1)

NOTE 1: get_choice() 함수 
  - 'a, 'b', 'c', 'q' 값만을 리턴할 수 있도록 정의 
  - Enter를 누를 때마다 생성되는 개행문자를 처리하기 위해, 입력 라인의 첫 문자만 읽고 나머지는 버림
NOTE 2: switch 문
  - default는 디버깅을 쉽게 할 수 있도록 사용됨 

#include <stdio.h>
char get_choice(void);
void count(void);
int main(void){
	int choice;
    
    while((choice = get_choice()) != 'q'){
    	switch(choice){
            case 'a': printf("Apple\n");
            		  break;
            case 'b': printf("Banana\n");
            		  break;
            case 'c': printf("\n");
            		  break;
            default : printf("Program Error\n");
            		  break;
        }
    }
	return 0;
}

char get_choice(void){
	int ch;
    printf("a,b,c,q 중 하나를 선택하시오.\n");
    printf("a. 조언      b. 경고\n");
    printf("c. 카운트    q. 종료\n");
    ch = get_first();
    
    while( ( ch < 'a' || ch > 'c') && ch != 'q' ){
    	printf("a, b, c, q 중 하나를 선택해야 합니다. \n");
        ch = get_first();
    }
	
    return ch;
}
char get_first(void){
	int ch;
    ch = getchar();
    
    while(getchar() != '\n') continue;
    
    return ch;

}

 

 

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

char showmenu(void);
void eatline(void);	// 라인의 끝까지 읽는다. 
void show(void (* fp)(char *), char *str);	
void ToUpper(char *);	// 문자열을 대문자로 변환
void ToLower(char *);	// 문자열을 소문자로 변환
void Transpose(char *);	// 대소문자를 교차 변환함 
void Dummy(char *);		// 원본 문자열을 그대로 둔다. 

int main(void){
    char line[81];
	char copy[81];
    char choice;
    void (*pfun)(char *);	// char * 전달인자를 사용하고 리턴값이 없는 함수를 가리킴 
    
	while(gets(line) != NULL && line[0] != '\n'){'
    	while((choice = showmenu()) != 'n'){
    		switch(choice){	    // switch가 포인터로 설정함
        		case 'u': pfun = ToUpper;	break;
            	case 'l': pfun = ToLower;	break;
            	case 't': pfun = Transpose;	break;
            	case 'o': pfun = Dummy;		breal;
        	}
     		strcpy(copy, line); // show()에 전달한 문자열을 복사한다. 
        	show(pfun, copy);	// 선택된 함수를 사용한다.     
       	}
        puts("문자열을 입력하시오 (끝내려면 빈라인)");
     }
    puts("안녕!");
}

char showmenu(void){
	char ans;
    puts("메뉴에서 원하는 작업을 선택하시오:"); 
    puts("u) 대문자로 변환        l) 소문자로 변환");
    puts("t) 대소문자로 교차 변환  o) 원본 그대로");
    puts("n) 다음 문자열");
    
    ans = getchar();		// 사용자로부터 응답을 읽는다. 
    ans = tolower(ans);		// 소문자로 변환한다. 
    eatline();				// 라인의 나머지를 읽어서 폐기한다. 
    while(strchr("ulton", ans) == NULL){
    // 문자열 'ulton'에서 문자 ans가 처음 나타나는 위치를 찾아, 그 위치를 가리키는 
    // 포인터를 리턴함. 그 문자를 찾지 못하면 널 포인터를 리턴함 
    // 위 루프 검사는 아래 검사의 축약판이다. 
    // while(ans != 'u' && ans != 'l' && ans != 't'  && ans != 'o' && ans != 'n' )
    // 검사항목이 많을수록 strchr()를 사용하는 것이 훨씬 편리하다. 
    	puts("u,l,t,o,n 중에서 하나를 선택하시오:");
        ans = tolower(getchar());
        eatline();
    }
	
    return ans;
}

void eatline(void){
	// 입력 라인의 나머지를 읽어 폐기한다. 
	// 선택을 입력하기 위해 사용자는 문자를 입력 후, Enter를 누를 때, 개행문자가 붙여진다. 
    // 이 개행 문자를 폐기하지 않으면, 다음 번 사용자의 응답으로 읽혀진다. 
    // 또한 첫 문자를 읽은후, 나머지는 모두 폐기한다. 
	while (getchar() != '\n'){
    	* str = toupper( * str);
        contine;
    }
}
void ToUpper(char *str){
	while (*str){
    	* str = toupper(*str);
        str ++;
    }
}
void ToLower(char *str){
	while (*str){
    	* str = tolower(*str);
        str ++;
    }
}
void Transpose(char *str){
	while (*str){
    	if (islower(*str)) * str = toupper(*str);
        else if (isupper(*str)) *str = tolower(*str);
        str ++
    }
}
void Dummy(char *str){}

void show(void (*fp)(char *), char *str){
	(*fp)(str);		// 선택한 함수를 str에 적용한다. 
    puts(str);		// 결과를 표시한다. 
}
728x90

댓글