IT_Programming/C · C++

[C] 간단하게 만든 (콘솔) 고객 정보 관리 프로그램 (파일 입출력)

JJun ™ 2009. 6. 22. 12:33

================================================================================================ 

구조체 + 파일 입출력 + 동적할당 및 포인터 연습하기...

지루하다... 빨리 지나갔으면....ㅜ_ㅠ;

================================================================================================ 

 

[실행화면]

 

 

 

 

================================================================================================

 

[소스코드]

 

/**********************************/

/* 작성자 : creazier (블로그 주인장) */

/**********************************/

 

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

 

#define SIZE                 20
#define SAFE_FREE(p)   if(p) { free(p); p=NULL; }
#define FILE_NAME       "student.txt" 

 

typedef struct
{
     char name[20];
     int age;
     char phone[20];
} customer; // struct 사용자 타입 선언

 

void menu_print();
customer* insert_info(customer *cus, int *size);
void delete_info(customer *cus, int *size, char *name);
void search_info(customer *cus, int *size, char *name);
void printList(customer *cus, int *size);
int get_fileLine(FILE *f);
customer* get_fileList(int *s);
void put_fileList(customer *cus, int *size);

 

int main(void)
{
     int menu_num, size = 0;                                        // index_location : 추가할 인덱스의 위치

     char *name = (char *)malloc(sizeof(char) * SIZE);  // 이름을 입력 받을 동적 메모리 할당
 
     customer *cus = get_fileList(&size); // struct 사용자 정의 타입 동적 메모리 할당
     memset(name, '\0', SIZE);

     while(1)
     {
          menu_print();
          scanf("%d", &menu_num);

          switch(menu_num) // 입력된 메뉴별 실행
          {
                case 1  : cus = insert_info(cus, &size);                     break;
                case 2  : delete_info(cus, &size, name);                   break;
                case 3  : search_info(cus, &size, name);                  break;
                case 4  : printList(cus, &size);      break;
                case 5  : printf("파일에 저장하고 종료합니다.\n\n"); 
                              put_fileList(cus, &size);                             exit(0);
                default : printf("메뉴 번호를 확인하세요\n\n");           break;
          }
     }

     SAFE_FREE(name); // 동적 메모리 해제
     SAFE_FREE(cus);  // 동적 메모리 해제

     return 0;
}

void menu_print() // 메뉴 출력
{
     printf("\n*****************************************\n");
     printf("* 1. 입력 \n");
     printf("* 2. 삭제 \n");
     printf("* 3. 검색 \n");
     printf("* 4. 목록 출력 \n");
     printf("* 5. 종료 \n");
     printf("*****************************************\n");
     printf("메뉴 번호를 입력하세요 : ");
}

 

customer* insert_info(customer *cus, int *size) // 데이터 삽입 (확장된 메모리를 돌려준다.)
{
     customer *expand_cus;
     printf("\n[입력 메뉴]\n추가할 정보를 입력하세요\n");
 
     // 추가될때마다 동적 메모리 재할당!
     expand_cus = (customer *)malloc(sizeof(customer)*(*size) + sizeof(customer));
     memcpy(expand_cus, cus, sizeof(customer)*(*size)); // 원본 내용 카피

 

     printf("  이름 : "); fscanf(stdin, "%s", &expand_cus[(*size)].name);
     printf("  나이 : "); fscanf(stdin, "%d", &expand_cus[(*size)].age);
     printf("연락처 : "); fscanf(stdin, "%s", &expand_cus[(*size)].phone);
     printf("%s님의 정보가 추가되었습니다.\n", expand_cus[(*size)].name);

     (*size)++;

 

     return expand_cus;
}

 

void delete_info(customer *cus, int *size, char *name) // 데이터 삭제
{
     int i, flag = 0;
   
     if(*size > 0)
     {
        printf("[삭제 메뉴]\n삭제할 정보를 입력하세요\n");
        printf("  이름 : ");
    
        memset(name, '\0', SIZE); 
        fflush(stdin);
        fgets(name, SIZE, stdin);
        *(name + (strlen(name) - 1)) = '\0';

 

        for(i=0; i<SIZE; ++i)
        {
                if(!strcmp(cus[i].name, name))
                {
                      printf("%s님의 정보가 삭제 되었습니다.\n", cus[i].name);
                      memmove(cus + i, cus + i + 1, sizeof(customer)*(*size)); // 중간에 공간 밀어넣기(삭제)

                      (*size)--;
                      flag = 1;
                }
        }

 

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


}

 

void search_info(customer *cus, int *size, char *name) // 데이터 검색
{
     int i;
     printf("\n이름을 입력하세요 : ");
  

     memset(name, '\0', SIZE); 
     fflush(stdin);
     fgets(name, SIZE, stdin);
     *(name + (strlen(name) - 1)) = '\0';

 

     printf("\n******* [검색 결과] *******\n");

     for(i=0; i<(*size); ++i)
     {       
          if(!strcmp(cus[i].name, name))
          {
               printf(" %5s   %5d   %5s\n", cus[i].name, cus[i].age, cus[i].phone);
          }

     }
     printf("***************************\n\n");
}

 

void printList(customer *cus, int *size) // 데이터 리스트 출력
{
     int i;
   
     if(*size > 0)
     {
            printf("\n[목록출력]\n");
            printf("----------------------------------\n");
            printf("    이름      나이       연락처   \n");
            printf("----------------------------------\n");

 

            for(i=0; i<(*size); ++i)
            {
                  printf("[%d] %5s %7d     %7s\n", i+1, cus[i].name, cus[i].age, cus[i].phone);
            }
     }
     else
     {
           printf("데이터가 없습니다.\n");
     }

 

     printf("\n");
}

 

int get_fileLine(FILE *f) // 파일의 라인 수 리턴
{
    int size = 0;
    char ch;

 

    while((ch = fgetc(f)) != EOF)
    {
        if(ch == '\n')
            ++size;
    }

   

    return size;
}

 

customer* get_fileList(int *s) // 파일의 내용을 구조체를 동적 할당 한 후에 담는다. (사이즈도 세팅)
{
    int size = 0, index = 0;
    FILE *f = fopen(FILE_NAME, "r+");
    customer *cus;

 

    if(f == NULL)
    {
        printf("파일이 없습니다.\n");
        exit(1);
    }

   

    *s = size = get_fileLine(f); // 사이즈 세팅

  //  if(size == 0)
  //  {
  //      printf("파일에 내용이 없습니다.\n");
  //      exit(1);
  //  }
 
    cus = (customer *)malloc(sizeof(customer) * size);

    fseek(f, 0l, SEEK_SET);
    while(index < size)
    {
        fscanf(f, "%s %d %s", &cus[index].name, &cus[index].age, &cus[index].phone);
        index++;
    }

 

    fclose(f);

 

    return cus;
}

 

void put_fileList(customer *cus, int *size) // 구조체의 내용들을 파일에 쓴다.
{
    int index = 0;
    FILE *f = fopen(FILE_NAME, "r+");
 
    if(f == NULL)
    {
        printf("파일이 없습니다.\n");
        exit(1);
    }

 

    fseek(f, 0l, SEEK_SET);
   
 while(index < *size)
    {
        fprintf(f, "%s %d %s\n", cus[index].name, cus[index].age, cus[index].phone);
        index++;
    }

 

    fclose(f);
}

 

================================================================================================