본문 바로가기
프로그래머의 길/C & C++

데이터를 파일로 입출력하는 프로그램

by 제이콥케이 2007. 3. 22.
반응형

프로그램 설명 :

데이터를 입력받아 파일에 저장할 수 있으며(누적 저장)
파일에 있는 데이터를 읽어와서 화면에 출력해준다.

삭제시에는 데이터를 실제로 삭제하는 것이 아니라 flag를 두어서 체크 하고(999)
체크한 데이터는 출력 및 검색이 되지 않는다.

체크한 flag를 다시 해제해서 데이터를 복구한것처럼 보여줄 수 있다.
fread(), fwrite(), fseek() 등 다양한 함수를 사용했다.

혼자 공부하기에 많은 도움이 될 프로그램이라고 생각된다.
중요한 부분은 표시 하였다. 중점으로 봐라!!


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

typedef struct
{
 char name[10];
 int kor;
 int eng;
 int mat;
 int tot;
 double avg;
 int check;

}RE;

int kb(RE *p);
void list();
void input();
void menu();
void search();
void all_avg();
void data_delete();
void un_delete();


int kb(RE *p)
{
 char temp[100];

 fflush(stdin);

 printf("이름 : ");
 gets(temp);

 if(temp[0]=='\0')
  return -1;

 strcpy(p->name, temp);

 printf("점수 : ");
 scanf("%d%d%d", &p->kor, &p->eng, &p->mat);

 p->tot = p->eng+p->kor+p->mat;
 p->avg = p->tot/3.0;

 return 1;
}

void list()
{
 FILE *ifp;
 RE rec;

 ifp = fopen("test.txt", "r");

 while(fread(&rec, sizeof(RE), 1, ifp) != 0)   // 읽기 실패하면 0을 리턴한다.
  if(rec.check != 999)  // 999는 삭제된 데이터
   printf("%s %d %d %d %d %.1lf\n", rec.name, rec.kor, rec.eng, rec.mat, rec.tot, rec.avg);  
 
 fclose(ifp);
}

void input()
{
 FILE *ofp;
 RE *sp = (RE *)calloc(1, sizeof(RE));

 ofp = fopen("test.txt", "a");

 while(kb(sp) != -1)
 {
  fwrite(sp, sizeof(RE), 1, ofp);
 
  free(sp);
  sp = (RE *)malloc(sizeof(RE));
 }
 fclose(ofp);
}

void menu()
{
 printf("1. 입력\n");
 printf("2. 출력\n");
 printf("3. 검색\n");
 printf("4. 전체평균\n");
 printf("5. 삭제\n");
 printf("6. 복구\n");
 printf("7. 종료\n");
}

void search()
{
 FILE *ifp;
 RE rec;
 char temp[15];
 int flag;

 ifp = fopen("test.txt", "r");

 printf("검색할 이름을 입력하세요 : ");
 scanf("%s", &temp);

 while(fread(&rec, sizeof(RE), 1, ifp) != 0)
 {
  flag =0;
  if(strcmp(rec.name, temp)==0)
  {
   if(rec.check != 999)
   {
    printf("%s %d %d %d %d %.1lf\n", rec.name, rec.kor, rec.eng, rec.mat, rec.tot, rec.avg);  
    flag = 1;
    break;
   }
  }
 }

 if(flag == 0)
  printf("데이터가 없습니다.\n");
 
 fclose(ifp);
}

void all_avg()
{
 FILE *ifp;
 RE rec;
 int count=0;
 double sum=0;
 
 ifp = fopen("test.txt", "r");

 while(fread(&rec, sizeof(RE), 1, ifp) != 0)
 {
  if(rec.check != 999)
  {
   sum += rec.avg;
   count++;
  }
 }

 printf("학생수 : %d 전체 평균 : %.2lf", count, sum/count);

 fclose(ifp);
}

void data_delete()
{
 FILE *ifp;
 RE rec;
 char temp[15];
 int flag=0;
 char ch;

 ifp = fopen("test.txt", "r+");  // fread를 쓰려면 'r'로 파일을 열어야 한다. 그러나 쓰기도 하고 싶다면 '+'를 추가
 
 printf("삭제할 이름을 입력하세요 : ");
 scanf("%s", &temp);

 while(fread(&rec, sizeof(RE), 1, ifp) != 0)
 {
  if(strcmp(rec.name, temp) == 0)  
  {
   if(rec.check == 999)
    continue;
   
   printf("%s %d %d %d %d %.1lf\n", rec.name, rec.kor, rec.eng, rec.mat, rec.tot, rec.avg);  
   printf("위 데이터를 삭제하시겠습니까?(y/n) : ");

   fflush(stdin);
   scanf("%c", &ch);

   if(ch == 'n')
   {
    fclose(ifp);
    printf("취소되었습니다. \n");    
    return;
   }
   else
   {
    rec.check = 999;
    fseek(ifp, -(int)sizeof(RE), SEEK_CUR);    
    fwrite(&rec, sizeof(RE), 1, ifp);
    flag = 1;      
    break;
   }
  }
 }

 fclose(ifp);
 
 if(flag == 0)
  printf("데이터가 없습니다.\n");
 else
  printf("삭제 되었습니다.\n");    
}


void un_delete()
{
 FILE *ifp;
 RE rec;
 char temp[15];
 char ch;
 int flag=0;

 ifp = fopen("test.txt", "r");

 printf("삭제된 데이터 리스트\n");

 while(fread(&rec, sizeof(RE), 1, ifp) != 0)
 {
  if(rec.check == 999)
   printf("%s %d %d %d %d %.1lf\n", rec.name, rec.kor, rec.eng, rec.mat, rec.tot, rec.avg);  
 }
 fclose(ifp);

 ifp = fopen("test.txt", "r+");

 printf("복구할 데이터를 입력하세요 : ");
 scanf("%s", temp);

 while(fread(&rec, sizeof(RE), 1, ifp) != 0)
 {
  if(strcmp(rec.name, temp) != 0)
   continue;
 
  printf("%s %d %d %d %d %.1lf\n", rec.name, rec.kor, rec.eng, rec.mat, rec.tot, rec.avg);  
  printf("위 데이터를 복구 하시겠습니까?(y/n) : ");

  fflush(stdin);
  scanf("%c", &ch);

  if(ch == 'n')
  {
   fclose(ifp);
   printf("취소되었습니다. \n");    
   return;
  }
  else
  {
   rec.check = 0;
   fseek(ifp, -(int)sizeof(RE), SEEK_CUR);    
   fwrite(&rec, sizeof(RE), 1, ifp);
   flag = 1;      
   break;
  } 
 }

 if(flag == 0)
  printf("데이터가 없습니다.\n");
 else
  printf("복구 되었습니다.\n");
 
 
 fclose(ifp);
}


int main()
{
 char select;
 
 while(1)
 {
  system("cls");
  menu();
  select=getche();
  printf("\n");
 
  switch(select)
  {
  case '1':
   input();
   break;

  case '2':
   list();
   getche();
   break;
 
  case '3':
   search();
   getche();
   break;
 
  case '4':
   all_avg();
   getche();
   break;
   
  case '5':
   data_delete();
   getche();
   break;

  case '6':
   un_delete();
   getche();
   break;
 
  case '7':
   return 0;
 
  default:
   printf("잘못 입력\n");
   getche();
   break;
  }
 }
 return 0;
}



반응형

'프로그래머의 길 > C & C++' 카테고리의 다른 글

#define 함수 활용  (0) 2007.03.23
달력 알고리즘 & 프로그램  (0) 2007.03.22
파일 삭제, 이름 변경 함수 unlink(), rename()  (0) 2007.03.22
getchar()와 getche(), getch()의 차이점  (0) 2007.03.22
C 함수 [W]  (0) 2007.03.21