핸드폰 전화번호부 에뮬레이션 (Console)
/* ----------------------------------------------->
* phonebook_emulation.console.cpp
* 핸드폰 전화번호부 에뮬레이션
* Build by C Language
* 2005/08/21
* http://blog.naver.com/nara9yo
* nara9yo@kornet.net
<----------------------------------------------- */
#include <stdio.h>
#include <stdlib.h> // malloc(), free(), atoi(), system()
#include <string.h> // strlen(), strcpy(), strstr()
#include <ctype.h> // isdigit()
#define MAX_L 60 // 문자열 크기 최대값
#define MAX_P 10 // 전화번호 등록 최대 개수
// phonebook형 구조체
typedef struct {
char *name; // 이름
char *number; // 전화번호
char *group; // 그룹
}phonebook;
// 전역 변수
phonebook ph_book[MAX_P]; // 자료가 들어갈 구조체 배열 선언
int now_point = 0; // 현재위치 및 등록된 전화번호수 파악
// 함수 원형
void showmenu(void); // 메뉴 함수 원형
void input_new(void); // 신규 입력
char * input_data(void); // 자료 입력 함수
void clear_data(void); // 삭제 함수
void modify_data(void); // 변경 함수
void scanmenu(void); // 검색 메뉴 함수
void scan(int scan_type); // 검색 함수
void show_all(void); // 저장된 모든 전화번호 출력함수
void free_all(void); // 모든 메모리 해제 함수(초기화 함수)
void clear_kb(void); // stdin에 남아있는 여분의 문자 청소 함수
void clr_screen(void); // 화면 클리어 함수
int main(void)
{
int choice;
showmenu();
printf("n메뉴선택> _b");
scanf("%d", &choice);
while(choice != 5)
{
switch(choice)
{
case 1 : clr_screen();
input_new();
break;
case 2 : clr_screen();
clear_data();
break;
case 3 : clr_screen();
modify_data();
break;
case 4 : clr_screen();
scanmenu();
break;
default : puts("그것은 선택할 수 없습니다.");
}
clr_screen();
showmenu();
printf("n메뉴선택> _b");
scanf("%d", &choice);
}
puts("프로그램을 종료합니다!");
free_all(); // 자료 입력에 쓰인 모든 메모리를 해제한다
return 0;
}
// 메뉴 함수
void showmenu(void)
{
puts("핸드폰 전화번호부 에뮬레이션(Console)");
puts("1) 신규입력t2) 삭제");
puts("3) 변경tt4) 검색");
puts("5) 종료");
}
// 신규 입력 함수
void input_new(void)
{
extern phonebook ph_book[MAX_P];
extern int now_point;
int choice;
clear_kb(); // stdin에 남은 여분의 문자를 청소한다
while(1)
{
puts("신규 입력");
puts("1) 입력하기 t2) 이전 메뉴");
printf("메뉴 선택> _b");
scanf("%d", &choice);
clear_kb();
if(choice == 1)
{
// input_data()함수로부터 리턴값을 받아 자료를 저장한다
printf("이름: ");
ph_book[now_point].name = input_data();
printf("전화번호: ");
ph_book[now_point].number = input_data();
printf("그룹: ");
ph_book[now_point].group = input_data();
now_point++; // 전화번호 등록수 증가
clr_screen();
}
else if(choice == 2)
break;
else
{
puts("그것은 선택할 수 없습니다!n");
}
}
}
// 자료 입력 함수
char * input_data(void)
{
// 새문자열을 가리키는 포인터를 리턴한다
char temp[MAX_L]; // 임시 배열
char *pn; // 새 문자열을 가리키는 포인터
gets(temp); // 문자열을 입력받는다
pn = (char *)malloc(sizeof(char) * (strlen(temp) + 1));
strcpy(pn, temp); // 문자열을 더 작은 공간으로 복사한다
return pn; // 함수가 종료될 때 임시 배열인 temp는 소멸한다
}
// 삭제 함수
void clear_data(void)
{
extern phonebook ph_book[MAX_P];
extern int now_point;
int index, del_index; // del_index는 삭제될 번지
int func_exit = 0;
puts("전화번호 삭제");
if(now_point == 0)
{
puts("a입력된 전화번호가 없습니다!");
}
else
{
show_all();
puts("이전 메뉴:: 숫자 이외의 키");
while(1)
{
while(1)
{
printf("삭제하고자 하는 번지> _b");
if(scanf("%d", &del_index))
break;
else
{
func_exit = 1;
break;
}
}
if(func_exit == 1)
{
clear_kb();
break;
}
else
{
now_point--; // 등록수 조절
// 메모리를 해제한다
free(ph_book[del_index - 1].name);
free(ph_book[del_index - 1].number);
free(ph_book[del_index - 1].group);
// 삭제된 위치의 다음 요소들을 한칸씩 앞자리로 옮긴다
for(index = del_index - 1; index < now_point; index++)
{
ph_book[index].name = (char *)malloc(sizeof(char) * (strlen(ph_book[index + 1].name) + 1));
strcpy(ph_book[index].name, ph_book[index + 1].name);
free(ph_book[index + 1].name);
ph_book[index].number = (char *)malloc(sizeof(char) * (strlen(ph_book[index + 1].number) + 1));
strcpy(ph_book[index].number, ph_book[index + 1].number);
free(ph_book[index + 1].number);
ph_book[index].group = (char *)malloc(sizeof(char) * (strlen(ph_book[index + 1].group) + 1));
strcpy(ph_book[index].group, ph_book[index + 1].group);
free(ph_book[index + 1].group);
}
}
clr_screen();
puts("전화번호 삭제");
if(now_point == 0)
{
puts("a입력된 전화번호가 없습니다!");
break;
}
else
{
show_all();
puts("이전 메뉴:: 숫자 이외의 키");
}
} // while문 끝
} // else문 끝
}
// 변경 함수
void modify_data(void)
{
extern phonebook ph_book[MAX_P];
extern int now_point;
int mod_index;
int func_exit = 0;
char *temp;
puts("전화번호 변경");
if(now_point == 0)
{
puts("a입력된 전화번호가 없습니다!");
}
else
{
show_all();
puts("이전 메뉴 - 숫자 이외의 키, 변경하지않을 항목-엔터");
while(1)
{
while(1)
{
printf("변경 하고자 하는 번지> _b");
if(scanf("%d", &mod_index))
break;
else
{
func_exit = 1;
break;
}
}
clear_kb();
if(func_exit == 1)
break;
else
{
printf("이름: (기존)%s => (변경)", ph_book[mod_index - 1].name);
temp = input_data();
// temp의 길이를 조사하여 변경 실행 파악
// 만약 입력값이 없었다면 strlen(temp) == 0이므로 if문은 실행되지 않는다
if(strlen(temp))
{
free(ph_book[mod_index - 1].name); // 메모리를 해제한다
ph_book[mod_index - 1].name = temp; // 새로운 위치 저장
}
printf("전화번호: (기존)%s => (변경)", ph_book[mod_index - 1].number);
temp = input_data();
if(strlen(temp))
{
free(ph_book[mod_index - 1].number);
ph_book[mod_index - 1].number = temp;
}
printf("그룹: (기존)%s => (변경)", ph_book[mod_index - 1].group);
temp = input_data();
if(strlen(temp))
{
free(ph_book[mod_index - 1].group);
ph_book[mod_index - 1].group = temp;
}
}
clr_screen();
puts("전화번호 변경");
if(now_point == 0)
{
puts("a입력된 전화번호가 없습니다!");
break;
}
else
{
show_all();
puts("이전 메뉴 - 숫자 이외의 키, 변경하지않을 항목-엔터");
}
} // while문 끝
} // else문 끝
}
// 검색 메뉴 함수
void scanmenu(void)
{
int choice;
clear_kb(); // stdin에 남은 여분의 문자를 청소한다
puts("검색");
puts("1) 모두 보기tt2) 이름으로 검색");
puts("3) 번호로 검색tt4) 번지로 검색");
puts("5) 그룹으로 검색t6) 이전 메뉴");
printf("n메뉴선택> _b");
scanf("%d", &choice);
while(choice != 6)
{
switch(choice)
{
case 1 : clr_screen();
puts("모두 보기");
scan(1);
break;
case 2 : clr_screen();
puts("이름으로 검색");
scan(2);
break;
case 3 : clr_screen();
puts("번호로 검색");
scan(3);
break;
case 4 : clr_screen();
puts("번지로 검색");
scan(4);
break;
case 5 : clr_screen();
puts("그룹으로 검색");
scan(5);
break;
default : puts("그것은 선택할 수 없습니다.");
}
puts("1) 모두 보기tt2) 이름으로 검색");
puts("3) 번호로 검색tt4) 번지로 검색");
puts("5) 그룹으로 검색t6) 이전 메뉴");
printf("n메뉴선택> _b");
scanf("%d", &choice);
}
}
// 검색 함수
void scan(int scan_type)
{
extern phonebook ph_book[MAX_P];
extern int now_point;
int index, found_false = 1, all_digit = 1;
char temp[MAX_L]; // 검색어를 저장할 임시 배열
clear_kb(); // stdin에 남은 여분의 문자를 청소한다
if(now_point == 0)
{
puts("a입력된 전화번호가 없습니다!");
}
else
{
// 모두 보기
if(scan_type == 1)
{
show_all();
} // if문 끝
else
{
printf("검색어: ");
gets(temp); // 검색어를 입력받는다
// 이름으로 검색
if(scan_type == 2)
{
for(index = 0; index < now_point; index++)
{
if(strstr(ph_book[index].name, temp))
{
printf("[%d] %s / %s / %sn", index + 1, ph_book[index].name, ph_book[index].number, ph_book[index].group);
found_false = 0; // 검색어에 만족하는 요소를 발견하였다면 체크
}
}
}
// 번호로 검색
else if(scan_type == 3)
{
for(index = 0; index < now_point; index++)
{
if(strstr(ph_book[index].number, temp))
{
printf("[%d] %s / %s / %sn", index + 1, ph_book[index].name, ph_book[index].number, ph_book[index].group);
found_false = 0; // 검색어에 만족하는 요소를 발견하였다면 체크
}
}
}
// 번지로 검색
else if(scan_type == 4)
{
// 입력된 검색어가 숫자인지 판별하는 루틴
for(index = 0; index <= (signed)strlen(temp); index++)
{
if(!isdigit(temp[index]))
{
all_digit = 0;
}
}
// 숫자라면
if(all_digit)
{
index = atoi(temp) - 1; // 입력된 검색어를 정수형으로 변환한다.
if(index < 0 || index >= now_point)
{
puts("검색 범위가 잘못되었습니다!");
}
else
{
printf("[%d] %s / %s / %sn", index + 1, ph_book[index].name, ph_book[index].number, ph_book[index].group);
}
}
else
{
puts("검색어 입력이 잘못되었습니다!");
}
}
// 그룹으로 검색
else if(scan_type == 5)
{
for(index = 0; index < now_point; index++)
{
if(strstr(ph_book[index].group, temp))
{
printf("[%d] %s / %s / %sn", index + 1, ph_book[index].name, ph_book[index].number, ph_book[index].group);
found_false = 0; // 검색어에 만족하는 요소를 발견하였다면 체크
}
}
}
if(found_false)
{
printf("검색어 (%s)에 만족하는 내용을 발견하지 못하였습니다!n", temp);
}
putchar('n');
} // else문 끝
} // else문 끝
}
// 저장된 모든 전화번호 출력함수
void show_all(void)
{
extern phonebook ph_book[MAX_P];
extern int now_point;
int index;
for(index = 0; index < now_point; index++)
{
printf("[%d] %s / %s / %sn", index + 1, ph_book[index].name, ph_book[index].number, ph_book[index].group);
}
putchar('n');
}
// 모든 메모리 해제 함수
void free_all(void)
{
extern phonebook ph_book[MAX_P];
extern int now_point;
int index;
for(index = 0; index < now_point; index++)
{
free(ph_book[index].name);
free(ph_book[index].number);
free(ph_book[index].group);
}
}
// stdin에 남아있는 여분의 문자 청소 함수
void clear_kb(void)
{
char junk[80];
gets(junk);
}
// 화면 클리어 함수
void clr_screen(void)
{
system("cls");
}
