#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <Windows.h>
typedef enum _COMMAND
{
Exit,
Add,
Search,
PrintAll,
Remove,
} COMMAND;
typedef struct _USERDATA
{
char szName[32];
char szPhone[32];
struct _USERDATA* pNext;
}USERDATA;
#define FILE_NAME "PhoneBook.txt"
#define PRINT_ERR_MSG(msg) printf("ERROR: %s", msg);
USERDATA* phoneBook = NULL;
COMMAND print_menu()
{
COMMAND selectMenu;
printf("[1]Add\t[2]Search\t[3]Print all\t[4]Remove\t[0]Exit\n: ");
scanf("%d", &selectMenu);
getchar();
return selectMenu;
}
void write_userdate_to_file()
{
FILE* fp = NULL;
fp = fopen(FILE_NAME, "w");
if (fp != NULL)
{
int count = 0;
USERDATA* pCurrent = phoneBook;
while (pCurrent != NULL)
{
count++;
pCurrent = pCurrent->pNext;
}
fwrite(&count, sizeof(int), 1, fp);
pCurrent = phoneBook;
while (pCurrent != NULL)
{
int nameLength = strlen(pCurrent->szName);
int phoneLength = strlen(pCurrent->szPhone);
fwrite(&nameLength, sizeof(int), 1, fp);
fwrite(pCurrent->szName, sizeof(char), nameLength, fp);
fwrite(&phoneLength, sizeof(int), 1, fp);
fwrite(pCurrent->szPhone, sizeof(char), phoneLength, fp);
pCurrent = pCurrent->pNext;
}
fclose(fp);
}
return;
}
void load_userdata_from_file()
{
FILE* fp = NULL;
fp = fopen(FILE_NAME, "r");
if (fp != NULL)
{
int count = 0;
fread(&count, sizeof(int), 1, fp);
int nameLength = 0;
int phoneLength = 0;
USERDATA* pUser;
for (int i = 0; i < count; ++i)
{
// 유저데이터 메모리 할당
pUser = (USERDATA*)malloc(sizeof(USERDATA));
if (pUser != NULL)
{
memset(pUser, 0, sizeof(USERDATA));
// 이름 로드
fread(&nameLength, sizeof(int), 1, fp);
fread(pUser->szName, sizeof(char), nameLength, fp);
// 전화번호 로드
fread(&phoneLength, sizeof(int), 1, fp);
fread(pUser->szPhone, sizeof(char), phoneLength, fp);
// 폰북에 추가
USERDATA* pCurrent = phoneBook;
if (pCurrent == NULL)
{
phoneBook = pUser;
}
else
{
while (pCurrent->pNext != NULL)
{
pCurrent = pCurrent->pNext;
}
pCurrent->pNext = pUser;
}
}
}
fclose(fp);
}
return;
}
void load_userdata()
{
// 파일 로드
load_userdata_from_file();
return;
}
void save_userdata()
{
// 파일로 저장
write_userdate_to_file();
// 메모리 비우기
USERDATA* pCurrent = phoneBook;
while (pCurrent != NULL)
{
USERDATA* pDelete = pCurrent;
pCurrent = pCurrent->pNext;
free(pDelete);
}
}
void add_userdata()
{
USERDATA* pUser = (USERDATA*)malloc(sizeof(USERDATA));
memset(pUser, 0, sizeof(USERDATA));
if (pUser != NULL)
{
pUser->pNext = NULL;
// 이름 입력
printf("Input name : ");
gets_s(pUser->szName, sizeof(pUser->szName));
// 전화번호 입력
printf("Input phone number : ");
gets_s(pUser->szPhone, sizeof(pUser->szPhone));
// phoneBook에 추가
USERDATA* pCurrent = phoneBook;
if (pCurrent == NULL)
{
phoneBook = pUser;
}
else
{
while (pCurrent->pNext != NULL)
{
pCurrent = pCurrent->pNext;
}
pCurrent->pNext = pUser;
}
puts("추가 완료되었습니다.");
}
}
void print_all_userdata()
{
USERDATA* pCurrent = phoneBook;
while (pCurrent != NULL)
{
char* szName = pCurrent->szName;
char* szPhone = pCurrent->szPhone;
printf("[0x%p] %s\t%s [0x%p]\n", szName, szName, szPhone, szPhone);
pCurrent = pCurrent->pNext;
}
return;
}
USERDATA* search_userdata_of_name()
{
char szName[32] = { 0 };
printf("Input Name: ");
gets_s(szName, sizeof(szName));
USERDATA* pCurrent = phoneBook;
while (pCurrent != NULL)
{
if (strcmp(szName, pCurrent->szName) == 0)
{
break;
}
pCurrent = pCurrent->pNext;
}
return pCurrent;
}
void remove_userdata(const char* pszName)
{
USERDATA* pPrev = NULL;
USERDATA* pCurrent = phoneBook;
while (pCurrent != NULL)
{
char* szName = pCurrent->szName;
if (strcmp(szName, pszName) == 0)
{
// 데이터 삭제
if (pPrev == NULL)
{
phoneBook = NULL;
}
else
{
pPrev->pNext = pCurrent->pNext;
}
free(pCurrent);
break;
}
else
{
pPrev = pCurrent;
pCurrent = pCurrent->pNext;
}
}
puts("삭제 완료!");
return;
}
int process(COMMAND selectMenu)
{
switch (selectMenu)
{
case Exit:
return -1;
case Add:
{
add_userdata();
break;
}
case Search:
{
USERDATA* pUser = search_userdata_of_name();
if (pUser == NULL)
{
puts("검색된 사용자 정보가 없습니다.");
}
else
{
char* szName = pUser->szName;
char* szPhone = pUser->szPhone;
printf("[0x%p] %s\t%s [0x%p]\n", szName, szName, szPhone, szPhone);
}
}
break;
case PrintAll:
print_all_userdata();
break;
case Remove:
{
USERDATA* pUser = search_userdata_of_name();
if (pUser == NULL)
{
puts("데이터가 존재하지 않습니다. 다시 선택해 주세요.");
}
else
{
remove_userdata(pUser->szName);
}
}
break;
default:
break;
}
return 0;
}
int main(int argc, char* argv[])
{
load_userdata();
while (1)
{
COMMAND selectMenu = print_menu();
int result = process(selectMenu);
if (result == -1) break;
system("pause");
system("cls");
}
save_userdata();
puts("프로그램을 종료합니다.");
return;
}
'c언어' 카테고리의 다른 글
19. 전처리기 (0) | 2023.08.01 |
---|---|
18. 파일 입출력 (0) | 2023.08.01 |
17. 기본 자료구조 (0) | 2023.06.28 |
16. 구조체와 공용체 (0) | 2023.06.28 |
15. 함수에 대한 고급 이론 (0) | 2023.06.27 |