83.1 JSON 구조체 작성하기

특정 형식으로 된 텍스트 문서를 처리하여 프로그램에서 사용할 수 있도록 하는 것을 구문 분석 또는 파싱(parsing)이라고 하며 파싱을 하는 프로그램을 파서(parser)라고 부릅니다. 여기서 제대로 된 파서를 구현하는 일은 상당히 복잡하고 어려운 작업입니다. 우리는 C 언어를 배우는 것이 목적이므로 JSON을 완벽하게 처리하는 파서를 구현하기 보다는 간단한 형식의 JSON 문서를 이용하여 텍스트 처리 방법을 익혀보겠습니다.

먼저 JSON을 처리하기 위한 구조체를 만들어야 합니다. 파싱은 문장을 분해하여 토큰(token)으로 만드는 작업이므로 다음과 같이 토큰 구조체를 작성해야 합니다.

토큰은 문자열 토큰과 숫자 토큰으로 나뉘는데 토큰 종류를 구분하기 위한 TOKEN_TYPE 열거형을 정의해줍니다. 그리고 토큰 구조체 TOKEN은 토큰 종류, 문자열 포인터, 숫자 변수, 배열의 요소인지 표시하는 변수가 들어갑니다. 여기서 토큰의 값은 문자열 또는 숫자 한 종류만 저장하므로 union을 사용하여 공용체로 만듭니다.

// 토큰 종류 열거형
typedef enum _TOKEN_TYPE {
    TOKEN_STRING,    // 문자열 토큰
    TOKEN_NUMBER,    // 숫자 토큰
} TOKEN_TYPE;

// 토큰 구조체
typedef struct _TOKEN {
    TOKEN_TYPE type;    // 토큰 종류
    union {             // 두 종류 중 한 종류만 저장할 것이므로 공용체로 만듦
        char *string;       // 문자열 포인터
        double number;      // 실수형 숫자
    };
    bool isArray;       // 현재 토큰이 배열인지 표시
} TOKEN;

JSON 문서에 들어있는 숫자가 정수라 하더라도 double형 변수에 저장합니다. 실수는 값을 그대로 사용하면 되고, 정수는 값을 꺼낸 뒤 정수로 형변환을 하면 됩니다.

이제 JSON 구조체를 정의합니다. 간단하게 구현하기 위해 토큰은 배열로 만들었고, 개수를 20개로 제한했습니다.

#define TOKEN_COUNT 20    // 토큰의 최대 개수

// JSON 구조체
typedef struct _JSON {
    TOKEN tokens[TOKEN_COUNT];    // 토큰 배열
} JSON;

지금까지 정의한 구조체로 JSON의 키-값에서 문자열 값과 숫자값 그리고 문자열 배열을 처리해보겠습니다.