본문 바로가기
Computer & Program/잡다한 이모저모

이름과 숫자 1~4까지의 답 10개를 입력 받아 O,X 표시 및 평균 및 최고득점자와 최소 득점자 출력하는 로직

by TDRemon 2009. 3. 4.
반응형

// 이름과 숫자 1~4까지의 답 10개를 입력 받아 O,X 표시 및 평균 및 최고득점자와 최소 득점자 출력하는 로직
#include<stdio.h>
#include<windows.h>
#include<conio.h>

#define Read "c:\\saram.txt" // 데이터가 저장되어 있는 파일
#define Wirt "c:\\result.txt" // 결과값을 저장할 파일

int max=0, min=100; // max는 커져야 함을 0이고 min은 작아져야 함으로 100이다.
double avg=0;

struct AA // 사람 이름과 답을 저장해 놓은 구조체
{
 char name[10];
 char num[11];
};

void result(char *); // 데이터를 받아 계산한 후 result.txt로 저장하는 함수
void menu(char *); // 처음 select 화면을 보여주는 함수
void view(char *); // result.txt에 저장되어 있는 값을 보여주는 함수
void input(); // saram.txt에 데이터 추가 입력 하는 함수
void maxmin(); // 최대/최소 득점자와 점수 및 전체 평균값을 출력하는 함수

void main()
{
 char anwer[11];
 printf("정답을 입력해 주세요 : ");
 scanf("%s", anwer);
 result(anwer); // 문자열이기 때문에 주소값을 전달
 system("cls"); // 화면 클리어
 while(1)
 {
  menu(anwer); // menu의 포함된 함수에서 anwer의 주소값을 알아야 하기때문에 menu에도 주소값을 전달해야 한다
 }
}

void menu(char *anwer) // 받을때는 *를 붙여서 주소값임을 명시해줘야 한다
{
 char i;
 printf("1.Input data\n");
 printf("2.View data\n");
 printf("3.Max / Min\n");
 printf("4.Exit program\n");
 printf("Select number : ");
 i = getche();
 printf("\n");
 getch(); // 문자 하나를 입력받을 때 까지 대기하라는 함수
 system("cls"); // 화면 클리어
 switch(i){
  case '1' : input(); result(anwer); break; // 입력 받은 후에 입력 받은 데이터에 대해서도 계산을 해주어야 한다
  case '2' : view(anwer); break;
  case '3' : maxmin(); break;
  case '4' : exit(0);
 }
}

void maxmin()
{
 struct AA saram;
 int score;
 FILE *fp;
 fp = fopen(Wirt, "r"); // c:\\result.txt에서 그냥 읽어 옴
 while(1){
  fscanf(fp, "%s", saram.name); // fp에서 스트링 만큼을 읽어서 saram.name에 저장을 하라
  if(feof(fp)) // 파일을 끝까지 읽었나?
   break; // 그렇다면 break
  fscanf(fp, "%s", saram.num);
  fscanf(fp, "%d", &score);
  if(score==max){
   printf("최고점수는 %d점이고 %s의 점수이다.\n", max, saram.name);
  }
 }
 fclose(fp);
 FILE *tp; // 처음부터 다시 읽어야 하기때문에 새로 열어줘야 함
 tp = fopen(Wirt, "r");
 while(1){
  fscanf(tp, "%s", saram.name);
  if(feof(tp)) // feof(tp)는 반드시 하나의 입력 후에 실행해 주어야 한다. 안그러고 위에 넣으면 마지막 값이 2번 출력된 됨
   break;
  fscanf(tp, "%s", saram.num);
  fscanf(tp, "%d", &score);
  if(score==min){
   printf("최저점수는 %d점이고 %s의 점수이다.\n", min, saram.name);
  }
 }
 printf("평균 점수는 %.2lf이다.\n", avg); // 소수점 2째자리 가지 double형으로 출력하라
 getch();
 system("cls");
 fclose(tp);
}

void input()
{
 struct AA saram;
 FILE *fp;
 fp = fopen(Read, "a"); // 추가저장 "a", 처음부터 저장 "w", 읽어오기만 "r"
 printf("이름 ? : ");
 scanf("%s", saram.name);
 printf("답안 ? : ");
 scanf("%s", saram.num);
 fprintf(fp, "%s ", saram.name); // fprintf는 말 그래도 file에 printf 즉, 화면이 아닌 file에 기록하라는 것이다
 fprintf(fp, "%s\n", saram.num);
 fclose(fp);
 system("cls");
}

void view(char *anwer)
{
 char data[25];
 int cnt=0;
 FILE *fp;
 fp = fopen(Wirt, "r");

 printf("이름              점수\n");
 printf("======================\n");
 while(1)
 {
  fgets(data, 25, fp);
  if(cnt==3) // 결과 값을 3개 단위로 끊기 위한 if문
  {
   cnt=0;
   printf(".................more");
   getch();
   system("cls");
   printf("이름              점수\n");
   printf("======================\n");
   
  }
  if(feof(fp))
   break;
  printf("%s", data);
  cnt++;
 }
 printf(".................end\n");
 getch();
 system("cls");
 fclose(fp);
}

void result(char *anwer)
{
 struct AA saram;
 int i, l=0, k=0;
 FILE *temp1, *temp2;
 temp1 = fopen(Read, "r");
 temp2 = fopen(Wirt, "w");
 while(1)
 {
  k=0;
  fscanf(temp1, "%s", saram.name);
  if(feof(temp1))
   break;
  l++; // 몇명 읽어 들였는지 계산
  fprintf(temp2, "%s ", saram.name);
  fscanf(temp1, "%s", saram.num);
  for(i=0; i<10; i++){ // 입력된 값들과 하나씩 비교함
   if(anwer[i]==saram.num[i]){
    fprintf(temp2, "%c", '0'); // 맞으면 0을 기록
    k++;
   }
   else
    fprintf(temp2, "%c", 'X'); // 틀리면 X를 기록
  }
  k *= 10; // 10개에 100점 만점 이기 대문에 곱하기 10을 해줌
  fprintf(temp2, " %d\n", k);
  if(k>max){
   max = k;
  }
  if(k<min){
   min = k;
  }
  avg += k; // 누적으로 모든 점수들을 더해 나간다
 }
 avg /= l; // 총 개수로 나누어 주어 평균을 구한다.
 fclose(temp1);
 fclose(temp2);
}

이거는 순전히 나 혼자서 구현 했다는 의미에서 나에게는 감명 깊었던 프로그램이다. 지금까지 파일 입출력 및 포인터 개념에 막연한 두려움까지 안고 있던 나에게 구현하면서도 '과연 이렇게 해서 제대로 컴파일이 될까?'하는 막연함을 말끔히 없애줬다. 역시 완벽한 이론 아래 어설픈 실전 없다고... 아무튼 이걸로 나는 파일 입출력 및 포인터 개념을 확실하게 잡을 수 있었다. 물론 아직 갈길은 멀고도 멀고, 늦기도 애지간히 늦었지만 지금이라도 자신있는 첫발을 디딜수 있었다는 사실에 나는 기쁘다.
자세한 설명은 주석으로 다 달았기에 기타 설명은 쓰지 않겠다.

반응형

'Computer & Program > 잡다한 이모저모' 카테고리의 다른 글

구조체를 통한 링크드 리스트의 예  (0) 2009.03.04
문자열 출력 예  (0) 2009.03.04
포인터  (0) 2009.03.04
이름과 점수를 입력받아 관리하는 프로그램  (0) 2009.03.04
KMP 알고리즘...  (0) 2009.03.04

댓글