[C 언어] - Phone Book - v2

RuiN·2022년 8월 6일
0

Practice

목록 보기
2/4
post-thumbnail

이전에 Phone Book - v1 을 통해서 기본적인 전화번호부 조회 삭제 로직을 만들어 보았습니다.
이번에는 파일을 읽고 조회하고 삭제하고 추가하여 저장하는 것까지 해볼까합니다.

데이터의 배열을 이름순으로 정렬


Main ( )

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

#define CAPACITY 100
#define BUFFER_SIZE 20

char *names[CAPACITY];
char *numbers[CAPACITY];
int n = 0;

void add();
void find();
void status();
void delete();
void load();
void save();
int search(char *name);

int main() {
    char command[BUFFER_SIZE];
    while (1) {
        printf("$   ");
        scanf("%s", command);

        if ((strcmp(command, "add")) == 0) {
            add();
        } else if ((strcmp(command, "find")) == 0) {
            find();
        } else if ((strcmp(command, "delete")) == 0) {
            delete();
        } else if ((strcmp(command, "status")) == 0) {
            status();
        } else if ((strcmp(command, "read")) == 0) {
            load();
        } else if ((strcmp(command, "save")) == 0) {
            save();
        } else if ((strcmp(command, "exits")) == 0)
            break;
    }
    return 0;
}

이전 Phone Book - v1 과 구성은 비슷합니다.
load ( ) 와 save ( ) 함수를 추가하고,
search ( ) 함수도 추가했습니다. 자세한 사항은 아래에서 설명하겠습니다.


Load ( )

void load() {
    char fileName[BUFFER_SIZE];
    char namesTmp[BUFFER_SIZE];
    char numbersTmp[BUFFER_SIZE];

    scanf("%s", fileName);

    FILE *fp = fopen(fileName, "r");
    if (fp == NULL) {
        printf("Open failed.\n");
        return;
    }

    while ((fscanf(fp, "%s", namesTmp)) != EOF) {
        fscanf(fp, "%s", numbersTmp);
        names[n] = strdup(namesTmp);
        numbers[n] = strdup(numbersTmp);
        n++;
    }
    fclose(fp);
}
  • 파일 이름을 입력받을 fileName 배열을 선언
  • 파일을 " r " 로 읽기모드로 열고, 파일이 없으면 return 시킵니다.
  • fsacnf ( ) 함수로 파일내부에 이름들을 모두 읽고 namesTmp 배열에 이름을 모두 넣을 때까지 while 문을 실행
    • 또 fscanf ( ) 함수로 파일내부에있는 번호들을 numbersTmp 배열에 순서대로 넣어준다.
    • names 와 numbers 포인터 배열에 namesTmp 와 numbersTmp 배열을 복사하여 순서대로 넣어준다.
    • 마지막으로 n 을 증가시켜 갯수를 증가시킨다.
  • 마지막으로 fclose( ) 로 파일을 닫아준다.
    ( 파일을 열었으면 닫아줘야 한다 )

Add ( )

void add()
{
    char namesTmp[BUFFER_SIZE], numbersTmp[BUFFER_SIZE];
    scanf("%s", namesTmp);
    scanf("%s", numbersTmp);

    int i = n-1;
    while (i >= 0 && strcmp(names[i], namesTmp) > 0) {
        names[i + 1] = names[i];
        numbers[i + 1] = numbers[i];
        i--;
    }
    names[i + 1] = strdup(namesTmp);
    numbers[i + 1] = strdup(numbersTmp);

    n++;
    printf("%s was added successfully.\n", namesTmp);
}
  • 추가할 이름과 번호를 입력받을 namesTmp 와 numbersTmp 배열을 선언합니다
  • int i = n -1 ; >> 배열은 인덱스가 0 부터 시작하기때문에 총 인원에서 - 1
    ( ex - 10명인 경우 배열은 0 ~ 9 가 됨 )
  • while 문을 통해서 입력받은 이름을 넣어줄 공간을 확보한다.
    • strcmp ( ) 는 단순히 문자열을 비교하는것이 아니라 , strcmp ( x , y ) > x가 y 보다 더 크다면 양수를 return 하고 더 작으면 음수를 return
  • 그 다음 입력받은 이름과 번호를 names 와 numbers 포인터배열에 넣어준다
  • n ++ 로 인원 증가

Delete ( )

void delete()
{
    char namesTmp[BUFFER_SIZE];
    scanf("%s", namesTmp);

    int index = search(namesTmp);
    if (index == -1) {
        printf("No person named '%s' exists.\n", namesTmp);
        return;
    }
    int j = index;
    for (; j < n-1 ; j++) {
        names[j] = names[j + 1];
        numbers[j] = numbers[j + 1];
    }
    n--;
    printf("'%s' was deleted successfully.  \n", namesTmp);
}
  • 삭제할 데이터의 이름을 입력받을 namesTmp 배열 선언

  • search ( )

    • int search(char *name)
      {
      	int i;
          for (int i = 0; i < n; i++){
           	if(strcmp(name, names[i]) == 0 ){
              	return i;
              }
          }
          return -1;
      }
    • strcmp( ) 함수로 만약 입력받은 이름이 names 포인터 배열에 있는 이름과 같다면 i 를 return
      그게 아니면 -1 return
  • index 값이 -1 이면 찾을 수 없는것이므로 return

  • 해당되는 데이터를 찾았다면 데이터의 자리를 한칸씩 앞으로 당겨서 덮어 저장한다.

  • n -- 로 인원 1 감소


Find ( )

void find()
{
    char namesTmp[BUFFER_SIZE];
    scanf("%s", namesTmp);
    int index = search(namesTmp);
    if (index == -1) {
        printf("No person named '%s' exists.  \n", namesTmp);
    } else
        printf("%s\n", numbers[index]);
}
  • 찾을 이름을 입력받을 namesTmp 배열 선언
  • delete ( ) 와 마찬가지로 search( ) 함수로 index값 추출
  • 만약 찾을 수없다면 찾을수 없다는 메시지 출력
    찾으면 해당 index의 numbers를 출력

Status ( )

void status()
{
    int i ;
    for (int i = 0; i < n; ++i) {
        printf("%s %s\n", names[i], numbers[i]);
    }
    printf("Total %d persons \n", n);
}
  • Phone book -v1 과 동일

Complete

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

#define CAPACITY 100
#define BUFFER_SIZE 20

char *names[CAPACITY];
char *numbers[CAPACITY];
int n = 0;

void add();
void find();
void status();
void delete();
void load();
void save();
int search(char *name);

int main() {
    char command[BUFFER_SIZE];
    while (1) {
        printf("$   ");
        scanf("%s", command);

        if ((strcmp(command, "add")) == 0) {
            add();
        } else if ((strcmp(command, "find")) == 0) {
            find();
        } else if ((strcmp(command, "delete")) == 0) {
            delete();
        } else if ((strcmp(command, "status")) == 0) {
            status();
        } else if ((strcmp(command, "read")) == 0) {
            load();
        } else if ((strcmp(command, "save")) == 0) {
            save();
        } else if ((strcmp(command, "exits")) == 0)
            break;
    }
    return 0;
}

void load() {
    char fileName[BUFFER_SIZE];
    char namesTmp[BUFFER_SIZE];
    char numbersTmp[BUFFER_SIZE];

    scanf("%s", fileName);

    FILE *fp = fopen(fileName, "r");
    if (fp == NULL) {
        printf("Open failed.\n");
        return;
    }

    while ((fscanf(fp, "%s", namesTmp)) != EOF) {
        fscanf(fp, "%s", numbersTmp);
        names[n] = strdup(namesTmp);
        numbers[n] = strdup(numbersTmp);
        n++;
    }
    fclose(fp);
}

void save()
{
    int i;
    char fileName[BUFFER_SIZE];
    char tmp[BUFFER_SIZE];

    scanf("%s", tmp);
    scanf("%s",fileName);

    FILE *fp = fopen(fileName, "w");
    if (fp == NULL) {
        printf("Open failed.\n");
        return;
    }
    for (int i = 0; i < n; ++i) {
        fprintf(fp, "%s %s\n", names[i], numbers[i]);
    }

    fclose(fp);
}

void add()
{
    char namesTmp[BUFFER_SIZE], numbersTmp[BUFFER_SIZE];
    scanf("%s", namesTmp);
    scanf("%s", numbersTmp);

    int i = n-1;
    while (i >= 0 && strcmp(names[i], namesTmp) > 0) {
        names[i + 1] = names[i];
        numbers[i + 1] = numbers[i];
        i--;
    }
    names[i + 1] = strdup(namesTmp);
    numbers[i + 1] = strdup(numbersTmp);

    n++;
    printf("%s was added successfully.\n", namesTmp);
}

void delete()
{
    char namesTmp[BUFFER_SIZE];
    scanf("%s", namesTmp);

    int index = search(namesTmp);
    if (index == -1) {
        printf("No person named '%s' exists.\n", namesTmp);
        return;
    }
    int j = index;
    for (; j < n-1 ; j++) {
        names[j] = names[j + 1];
        numbers[j] = numbers[j + 1];
    }
    n--;
    printf("'%s' was deleted successfully.  \n", namesTmp);
}

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

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

void status()
{
    int i ;
    for (int i = 0; i < n; ++i) {
        printf("%s %s\n", names[i], numbers[i]);
    }
    printf("Total %d persons \n", n);
}
profile
어디까지 올라갈지 궁금한 하루

0개의 댓글