==============================================================================================
이전 버전에 파일을 새로 쓰는 방식에서 파일에 있는 플래그 값을 변경하여, 출력의 유무를 따진다.
즉, 실제 데이터는 남아있고, 프로그램 상에서는 이 플래그 값을 판단하여 출력을 결정한다.
==============================================================================================
[실행화면]
==============================================================================================
[소스코드]
/**********************************/
/* 작성자 : 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 "student2.txt"
typedef struct
{
char name[20];
int age;
char phone[20];
int iDel; // 출력 유무의 플래그 변수
} 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) // 데이터 삽입, 파일에 추가
{
FILE *f = fopen(FILE_NAME, "r+");
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);
expand_cus[(*size)].iDel = 1;
printf("%s님의 정보가 추가되었습니다.\n", expand_cus[(*size)].name);
fseek(f, 0l, SEEK_END);
fprintf(f, "%s %d %s %d\n", expand_cus[(*size)].name, expand_cus[(*size)].age,
expand_cus[(*size)].phone, expand_cus[(*size)].iDel);
fclose(f);
(*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);
cus[i].iDel = 0; // 삭제를 나타내는 플래그 변수 세팅
printf("삭제 정보: %s %d %s %d\n", cus[i].name, cus[i].age, cus[i].phone, cus[i].iDel);
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)) && cus[i].iDel == 1)
{
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)
{
if(cus[i].iDel == 1)
{
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 %d", &cus[index].name, &cus[index].age, &cus[index].phone,
&cus[index].iDel);
index++;
}
fclose(f);
return cus;
}
void put_fileList(customer *cus, int *size) // 파일 쓰기. 삭제 플래그를 실제로 파일에 입력
{
int index = 0;
FILE *f = fopen(FILE_NAME, "r+");
customer temp;
if(f == NULL)
{
printf("파일이 없습니다.\n");
exit(1);
}
fseek(f, 0l, SEEK_SET);
while(fscanf(f, "%s %d %s %d", &temp.name, &temp.age, &temp.phone, &temp.iDel) > 0)
{
if(temp.iDel != cus[index].iDel)
{
fseek(f, -1, SEEK_CUR);
fprintf(f, "%d\n", cus[index].iDel);
fseek(f, 1, SEEK_CUR);
}
index++;
}
fclose(f);
}
==============================================================================================
'IT_Programming > C · C++' 카테고리의 다른 글
[펌] C/C++ 퍼포먼스와 footprint (0) | 2009.06.25 |
---|---|
[펌] #pragma once 와 #pragma comment() (0) | 2009.06.24 |
[C] 간단하게 만든 (콘솔) 고객 정보 관리 프로그램 (파일 입출력) (0) | 2009.06.22 |
[C] 파일 복사 ( 한번에 복사! and 가변인수 함수 사용) (0) | 2009.06.21 |
[C_구조체 동적할당] 콘솔 기반 고객 관리 프로그램 (memmove() 함수 사용) (0) | 2009.06.17 |