82.8 실행 파일에서 명령 처리하기

C 언어에서 제공하는 실행 파일 옵션 기능을 활용하여 append, list, extract 명령을 처리해보겠습니다. 다음은 각 명령을 처리하는 과정입니다.

그림 82‑23 실행 파일에서 명령을 처리하는 과정

main.c 파일을 다음과 같이 작성합니다.

filearchive/filearchive/main.c

#include <stdio.h>     // 파일 처리 함수가 선언된 헤더 파일
#include <string.h>    // strcmp 함수가 선언된 헤더 파일
#include "archive.h"
#include "command.h"

int main(int argc, char *argv[])
{
    // 실행 파일에 지정된 옵션이 없을 때 프로그램 사용 방법 출력
    if (argc == 1)
    {
        printf("filearchive <명령> <파일명>\n\n");
        printf("명령:\n");
        printf("    append   파일 추가\n");
        printf("    list     파일 목록 출력\n");
        printf("    extract  파일 추출\n");
        return 0;
    }

    // 초기화
    PARCHIVE archive = initialize();
    if (archive == NULL)
        return -1;

    char *command = argv[1];
    char *filename = argv[2];

    if (strcmp(command, "append") == 0)        // 파일 추가 명령
    {
        if (!isExist(archive, filename))       // 아카이브 파일에 추가할 파일이 있는지 검사
        {
            // 파일이 중복되지 않으면 새 파일 추가
            if (append(archive, filename) == -1)
            {
                printf("%s 파일 추가 실패\n", filename);
            }
        }
        else
        {
            printf("이미 %s 파일이 추가되어 있습니다.\n", filename);
        }
    }
    else if (strcmp(command, "list") == 0)      // 파일 목록 출력 명령
    {
        list(archive);
    }
    else if (strcmp(command, "extract") == 0)   // 파일 추출 명령
    {
        if (isExist(archive, filename))         // 아카이브 파일에 추출할 파일이 있는지 검사
        {
            // 아카이브 파일에 파일이 있으면 파일 추출
            if (extract(archive, filename) == -1)
            {
                printf("%s 파일 추출 실패\n", filename);
            }
        }
        else
        {
            printf("%s 파일이 없습니다.\n", filename);
        }
    }

    finalize(archive);    // 파일 포인터 닫기, 모든 동적 메모리 해제

    return 0;
}

먼저 다음과 같이 실행 파일에 지정된 옵션이 없을 때 프로그램의 사용 방법을 출력해줍니다. 보통 명령행(command line) 프로그램에서 자주 볼 수 있는 형태입니다.

// 실행 파일에 지정된 옵션이 없을 때 프로그램 사용 방법 출력
if (argc == 1)
{
    printf("filearchive <명령> <파일명>\n\n");
    printf("명령:\n");
    printf("    append   파일 추가\n");
    printf("    list     파일 목록 출력\n");
    printf("    extract  파일 추출\n");
    return 0;
}

initialize 함수를 호출하여 아카이브 파일을 열고, 파일 정보와 파일 목록을 얻습니다.

// 초기화
PARCHIVE archive = initialize();
if (archive == NULL)
    return -1;
    

filearchive.exe <명령> <파일명> 형식이 될 것이므로 argv[1]은 명령, argv[2]는 파일명이 됩니다.

char *command = argv[1];
char *filename = argv[2];

이제 command의 내용을 판별하여 append이면 파일 추가, list이면 파일 목록 출력, extract이면 파일 추출을 합니다. 여기서 파일을 추가할 때 같은 이름으로 된 파일이 중복되지 않도록 isExist 함수로 검사를 해주고, 파일을 추출할 때는 아카이브 파일에 추출할 파일이 있는지 isExist 함수로 검사를 해줍니다.

    if (strcmp(command, "append") == 0)        // 파일 추가 명령
    {
        if (!isExist(archive, filename))       // 아카이브 파일에 추가할 파일이 있는지 검사
        {
            // 파일이 중복되지 않으면 새 파일 추가
            if (append(archive, filename) == -1)
            {
                printf("%s 파일 추가 실패\n", filename);
            }
        }
        else
        {
            printf("이미 %s 파일이 추가되어 있습니다.\n", filename);
        }
    }
    else if (strcmp(command, "list") == 0)      // 파일 목록 출력 명령
    {
        list(archive);
    }
    else if (strcmp(command, "extract") == 0)   // 파일 추출 명령
    {
        if (isExist(archive, filename))         // 아카이브 파일에 추출할 파일이 있는지 검사
        {
            // 아카이브 파일에 파일이 있으면 파일 추출
            if (extract(archive, filename) == -1)
            {
                printf("%s 파일 추출 실패\n", filename);
            }
        }
        else
        {
            printf("%s 파일이 없습니다.\n", filename);
        }
    }

모든 작업이 끝났으면 finalize 함수를 호출하여 파일 포인터를 닫고 모든 동적 메모리를 해제합니다.

    finalize(archive);    // 파일 포인터 닫기, 모든 동적 메모리 해제

지금까지 알아본 파일들의 포함 관계는 다음과 같습니다.

그림 82‑24 파일 아카이브 프로그램의 헤더 파일 포함 관계