2020. 4. 26.

[자료구조] 인프런 6. 전화번호부 v2.0 강의 정리


파일로 저장하고 로드하기, 알파벳 순으로 정렬


한줄당 한사람의 정보가 저장된다.
이름 전화번호가 입력된다.

#pragma warning(disable:4996)
#include
#include
//strcmp 사용


#define CAPACITY 100
// 최대 100명을 저장한다.
#define BUFFER_SIZE 20

char* names[CAPACITY]; // namses
//names numbers char*타입의 배열이다.
char* numbers[CAPACITY]; //phone numbers
int n = 0; //number of people in phone directory

void add();
void find();
void status();
void remove();
void load();
void save();

int main() {
char buffer[BUFFER_SIZE];
while (1) {
printf("$ ");
// 프롬프트에 출력을 한다.
scanf("%s", buffer);
// 입력을 받아 command라는 배열에 저장한다.

if (strcmp(buffer, "read") == 0)
// load 명령어 추가
load();
else if (strcmp(buffer, "save") == 0)
// sava 명령어 추가
save();
else if (strcmp(buffer, "add") == 0)
// strcmp함수는 두 문자열이 동일하면 0을 반환한다.
add();
else if (strcmp(buffer, "find") == 0)
// find를 입력하면 find
find();
else if (strcmp(buffer, "status") == 0)
status();
else if (strcmp(buffer, "delete") == 0)
remove();
else if (strcmp(buffer, "exit") == 0)
break;
//exit를 입력하면 while문을 빠져나간다.
}
return 0;
}

//아래단에 추가

void load() {
char fileName[BUFFER_SIZE];
char buf1[BUFFER_SIZE];
char buf2[BUFFER_SIZE];

scanf("%s", fileName);
//파일 이름을 입력 받는다.

FILE* fp = fopen(fileName, "r");
// 파일에 접근하기 위해서는 먼저 파일을 열어야(open)해야 한다.
if (fp == NULL) {
// 파일을 여는데 실패한다면(디렉토리가 다르거나 파일명이 틀림)
printf("Open failed.\n");
return;
}

while ((fscanf(fp, "%s", buf1) != EOF)) {
// 파일의 끝에 도달할 때까지 반복해서 이름과 전화번호를 읽어서 배열에 저장한다.
// 여기까지오면 성공적으로 파일을 읽은것이다.
// fscanf(파일포인터,포맷스트링,실제로 읽어올 파일변수)
// fsscanf 는 파일의 끝에 도달하면 EOF를 리턴해준다.
// EOF 을 리턴하기 전까지 돈다.
fscanf(fp, "%s", buf2);
// 전화번호를 읽는것
names[n] = strdup(buf1);
numbers[n] = strdup(buf2);
n++;
}
fclose(fp);
//볼일이 끝난 파일은 반드시 닫아 주어야 한다.
}

// 파일을 열때는 save as로 한다.
void save() {
int i;
char fileName[BUFFER_SIZE];
char tmp[BUFFER_SIZE];

FILE* fp = fopen(fileName, "w");
// 파일에 쓸 때는 모드를 'w'로 하고 열어야 한다.
if (fp == NULL) {
printf("Open failed.\n");
return;
}
for (i = 0; i < n; i++) {
fprintf(fp, "%s %s\n", names[i], numbers[i]);
}
fclose(fp);
}

*데이터를 정렬된 상태로 유지하려면

bubblesort 등의 정렬(sorting) 알고리즘을 사용하는 방법
새로운 데이터가 계속적으로 추가되는 우리의 상황에서는 부적절
새로운 데이터가 추라될 때마다 제자리를 찾아서 삽입하는 방법


add 변경해줘야한다.


void add() {
char buf1[BUFFER_SIZE], buf2[BUFFER_SIZE];
scanf("%s", buf1);
scanf("%s", buf2);

int i= n-1;
while(i>0 && strcmp(names[i], buf1) >0) {
// i 1씩 줄어들면서 전에 입력된 데이터의 크기와
// 비교하여 새로입력된 buf1이 더 크면 0을 반환하고
// 반대의 경우에는 양수를 반환한다.
// strcmp함수는 사전식 순서를 반환할때도 사용할수 있다.
names[i+1] = names[i];
// 한칸 뒤로 옮긴다.
numbers[i+1] = numbers[i];
// 한칸 뒤로 옮긴다.
i--;
}
// 사전식 순서로 나보다 큰 항목들은 모두 한 칸씩 뒤로 이동시키고,
// 처음으로 나보다 작은 항목이 나오면 그것 바로 뒤에 삽입한다.
names[n] = strdup(buf1);
numbers[n] = strdup(buf2);
n++;
printf("%s was added successfully. \n", buf1);
}

remove 변경

void remove() {
char buf[BUFFER_SIZE];
scanf("%s", buf);
// 사람 이름을 입력받는다.
int index = search(buf);
// returns -1 if not exists
// search 함수가 대신 찾아준다.
if (index == -1) {
printf("No person named '%s' exists.\n", buf);
return;
}
int j = index;
for (j; j < n-1; j++) {
names[j] = names[j + 1];
numbers[j] = numbers[j + 1];
}
n--;
printf("'%s' was deleted successfully. \n", buf);
}

find 변경

void find() {
char buf[BUFFER_SIZE];
scanf("%s", buf);
int index = search(buf);
if (index == 1)
printf("No person named '%s' exists.\n", buf);
else
printf("%s\n", numbers[index]);
}


search 함수 추가

int search(char* name) {
int i;
for (i = 0; i < n; i++) {
if (strcmp(name, names[i]) == 0){
return i;
}
}
return -1;
}


댓글 없음:

댓글 쓰기