//객체지향 프로그래밍 2012.05.25 메뉴 성적
//200911636 박정욱
#include<iostream>
#include<iomanip>
#include<string>
using namespace std;
#define NUM_OF_SUBJECTS 3 //과목 갯수
#define MAX_NUM_OF_STUDENTS 100 //총 학생 수
#define MAX_NAME_SIZE 11 //최대 이름 입력 크기(영문 11 한글 5)
#define INPUT_CANCLE -1 //입력 취소(학번)
#define NONE 0 //0
//자료 입력 switch문의 case들
enum MENU {INPUT_DATA=1, SHOW_DATA, QUIT, MENU_AGAIN};
//자료 입력 2번째 for문의 switch문의 case들
enum FOR_j {SNUMBER = -2, NAME, KOREAN, ENGLISH, MATH, SUM, AVERAGE, GRADE, DONE};
struct student
{
int snumber; //학번
string name; //이름
float score[5]; //국 영 수 총점 평균
char grade; //평점
};
void show_menu(); //메뉴목록을 보여주는 함수.
int transfer_key(char cin_key); //사용자로부터 입력받은 키(1,2,q)를 int형으로 바꾸어준다;(메인함수의 키 입력 스위치문을 보기쉽게 하기 위함.)
int input_snumber(); //사용자로부터 9자리의 학번을 입력 받거나 입력취소 -1을 입력받아 리턴하는 함수.
void input_score(float* subject_score); //사용자로부터 0~100사이의 점수를 입력받아 저장시켜주는 함수.
void main()
{
int i,j; //for문을 이용하시위해 필요한 변수 i와 j.
int stopped_at=NONE, //사용자가 입력을 중단했을때, 중단했던 위치(i번째)를 저장시킬 변수.
key; //cin_key를 int형으로 바꿔 저장시킬 변수.(switch문의 case를 int형으로 바꾸기 위해)
char cin_key; //사용자로부터 메뉴번호를 입력받을 변수.(1,2,q)
//학생반 생성
student class_B[MAX_NUM_OF_STUDENTS]; //class B반의 학생들을 생성. MAX_NUM_OF_STUDENTS = 100
//메뉴 무한루프
do
{
show_menu(); //메뉴함수 호출; 1.자료입력 2.입력결과 q.종료/
cin >> cin_key; //사용자가 메뉴번호를 입력
key=transfer_key(cin_key); //입력한 메뉴번호 (1,2,q,그 외)를 인트형으로 바꾼다(1->INPUT_DATA=1 2->SHOW_DATA=2 q->QUIT=3 그 외-> MENU_AGAIN=4)
switch(key)
{
case INPUT_DATA : //자료입력
for(i=stopped_at ;i<MAX_NUM_OF_STUDENTS ;i++) //멈춘 곳 부터 총 학생 수까지 입력.첫 입력시 멈춘 곳(stopped_at)은 0이다.
{
for(j=SNUMBER; j< DONE; j++) //학번,이름,국,영,수는 사용자가 입력, 총합,평균,평점은 자동으로 구하는 함수 호출.
{ switch(j)
{ case SNUMBER : //학번 입력 : 학번 입력하는 함수 호출 input_snumber()
class_B[i].snumber=input_snumber();
//입력받은 학번이 -1 일 경우 2중 for문을 탈출하기 위해 goto문을 활용. case INPUT_DATA의 끝으로 이동한다. stopped_at변수에 i 대입.
if(class_B[i].snumber==INPUT_CANCLE)
{ cout <<"입력을 취소합니다.\n"; stopped_at=i; goto BREAK_OUT;}
break;
case NAME : //이름 입력 : 한글 5자이하의 이름을 입력. 이름의 크기가 MAX_NAME_SIZE=11을 초과하면 do while문에 의해 재입력.
do
{ cout <<"5자 이내의 이름을 입력하세요.(6자 이상은 성을 포함해 앞글자 5자리까지 입력.)\n";
cout <<"이름 : "; cin >> class_B[i].name;
}while(class_B[i].name.size() > MAX_NAME_SIZE); break;
case KOREAN : //점수를 입력받는 함수 호출 - 0~100사이의 수만 입력된다.
cout <<"국어 : ";
input_score(&class_B[i].score[KOREAN]);
break;
case ENGLISH : //점수를 입력받는 함수 호출 - 0~100사이의 수만 입력된다.
cout <<"영어 : ";
input_score(&class_B[i].score[ENGLISH]);
break;
case MATH : //점수를 입력받는 함수 호출 - 0~100사이의 수만 입력된다.
cout <<"수학 : ";
input_score(&class_B[i].score[MATH]);
break;
case SUM : //총합을 구한다.
class_B[i].score[SUM] = class_B[i].score[KOREAN] + class_B[i].score[ENGLISH] + class_B[i].score[MATH]; break;
case AVERAGE : //평균을 구한다.
class_B[i].score[AVERAGE] = class_B[i].score[SUM]/NUM_OF_SUBJECTS; break;
case GRADE : //평점을 구한다.
if(class_B[i].score[AVERAGE] >= 90) {class_B[i].grade='A';}
else if(class_B[i].score[AVERAGE] >= 80) {class_B[i].grade='B';}
else if(class_B[i].score[AVERAGE] >= 70) {class_B[i].grade='C';}
else if(class_B[i].score[AVERAGE] >= 60) {class_B[i].grade='D';}
else {class_B[i].grade='F';} break;
}
}
}
//break문이 없는 이유는 입력 완료 후, case SHOW_DATA로 바로가서 입력받았던 자료들을 보여주기 위함이다.
BREAK_OUT : //입력을 취소했을시 이쪽으로 온다.(학번 입력 중)
case SHOW_DATA : //입력 결과
if(stopped_at==NONE) {cout <<"입력된 데이터가 없습니다."<<endl;} //<-출력: 입력받은 자료가 없을경우
for(i=0 ; i < stopped_at;i++) //입력받았던 i번째 stopped_at 까지의 자료들을 보여준다.
{
cout<<i <<"▶ 학번 :"<<setw(10)<< class_B[i].snumber <<
"이름 : " << class_B[i].name <<endl<<
" 국어 : "<< class_B[i].score[KOREAN]<<
" 영어 : "<<class_B[i].score[ENGLISH]<<
" 수학 : "<<class_B[i].score[MATH]<<endl<<
" 총점 : "<< class_B[i].score[SUM]<<
" 평균 : "<<class_B[i].score[AVERAGE]<<
" 평점 : "<<class_B[i].grade<<endl;
}
key=MENU_AGAIN; break; //메뉴화면으로 돌아가기위해 key=(INPUT_DATA or SHOW_DATA) -> MENU_AGAIN로 바꾼다.
case QUIT : exit(1); break; //종료 : q입력했을시
default : cout << "1,2,q 중 하나만 선택하세요.\n";key=MENU_AGAIN;break; //<-출력 : 1,2,q이외의 키 입력시, 다시 메뉴화면으로 이동.
}
}while(key==MENU_AGAIN); //key=MENU_AGAIN인 동안 메뉴화면의 반복.
}
//메뉴화면 보여주는 함수.
void show_menu()
{
cout << "┏━━━━━━━━━━┓"<< endl;
cout << "┃1. 자료 입력 ┃"<< endl;
cout << "┃2. 입력 결과 ┃"<< endl;
cout << "┃q. 종료 ┃"<< endl;
cout << "┗━━━━━━━━━━┛"<< endl;
}
//char cin_key를 int형으로 바꾸어 리턴해주는 함수.
int transfer_key(char cin_key)
{
switch(cin_key)
{
case '1' : return INPUT_DATA; break;
case '2' : return SHOW_DATA; break;
case 'q' : return QUIT; break;
default : return MENU_AGAIN; break;
}
}
//학번 입력받는 함수(9자리로만).
int input_snumber()
{ int snum;
do
{ cout <<"학번 9자리를 입력하세요.(입력 취소 -1)\n";
cout <<"학번 : "; cin >> snum;
if(snum == -1) {break;} //-1 입력시 do while문 탈출 break
}while(snum/100000000 <= 0 || snum/100000000 > 9);//100000000으로 나눈 값이 1보다 작거나 9보다 큰 경우 9자리가 아니므로 do while문으로 재입력.
return snum;
}
//점수 입력받는 함수(0~100점).
void input_score(float* subject_score)
{ cin >> *subject_score;
while(*subject_score > 100 || *subject_score < 0) //0~100점 사이가 아닐경우 재입력
{ cout<<"0~100의 점수를 입력하시오.\n";
cin >> *subject_score;
}
}