83.8 질문입니다
, 박 수용님이 작성#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdbool.h> #include <stdlib.h> #include <string.h> typedef enum _TOKEN_TPYE { TOKEN_STRING, TOKEN_NUMBER, } TOKEN_TPYE; typedef struct _TOKEN { TOKEN_TPYE type; union { char *string; double number; }; bool isArray; } TOKEN; #define TOKEN_COUNT 20 typedef struct _JSON { TOKEN tokens[TOKEN_COUNT]; } JSON; char *readFile(char *filename, int *readSize) { FILE *fp=fopen(filename,"rb"); if(fp==NULL) return NULL; int size; char *buffer; fseek(fp,0,SEEK_END); size=ftell(fp); fseek(fp,0,SEEK_SET); buffer=malloc(size+1); memset(buffer,0,size+1); if(fread(buffer,size,1,fp)<1) { *readSize=0; free(buffer); fclose(fp); return NULL; } *readSize=size; fclose(fp); return buffer; } void parseJSON(char *doc, int size, JSON *json) { int tokenIndex=0; int pos=0; if(doc[pos]!='{') return; pos++; while(pos<size) { switch(doc[pos]) { case'"': { char *begin = doc + pos + 1; char *end = strchr(begin,'"'); if(end==NULL) break; int stringLength=end - begin; json->tokens[tokenIndex].type = TOKEN_STRING; json->tokens[tokenIndex].string=malloc(stringLength+1); memset(json->tokens[tokenIndex].string,0,stringLength+1); memcpy(json->tokens[tokenIndex].string,begin,stringLength); tokenIndex++; pos = pos + stringLength+1; } case'[': { pos ++; while(doc[pos] != ']') { if(doc[pos] == '"') { char *begin = doc +pos +1; char *end = strchr(begin,'"'); if(end==NULL) break; int stringLength = end-begin; json->tokens[tokenIndex].type=TOKEN_STRING; json->tokens[tokenIndex].string=malloc(stringLength+1); json->tokens[tokenIndex].isArray=true; memset(json->tokens[tokenIndex].string,0,stringLength+1); memcpy(json->tokens[tokenIndex].string,begin,stringLength); tokenIndex++; pos=pos+stringLength+1; } pos++; } } case '0': case '1': case '2': case '3': case '4': case'5': case '6': case '7': case '8': case '9': case '-': { char *begin = doc+pos; char *end; char *buffer; end=strchr(doc+pos,','); if(end==NULL) { end=strchr(doc+pos,'}'); if(end==NULL) break; } int stringLength=end-begin; buffer = malloc(sizeof(stringLength+1)); memset(buffer,0,stringLength+1); memcpy(buffer,begin,stringLength); json->tokens[tokenIndex].type=TOKEN_NUMBER; json->tokens[tokenIndex].number=atof(buffer); free(buffer); tokenIndex++; pos=pos+stringLength+1; } break; } pos++; } } char *getString(JSON *json, char *key) { for(int i=0; i<TOKEN_COUNT; i++) { if(json->tokens[i].type==TOKEN_STRING && strcmp(json->tokens[i].string,key)==0) { if(json->tokens[i+1].type==TOKEN_STRING) return json->tokens[i+1].string; } } return NULL; } char *getArrayString(JSON *json, char *key, int index) { for(int i=0; i<TOKEN_COUNT; i++) { if(json->tokens[i].type==TOKEN_STRING && strcmp(json->tokens[i].string,key)==0) { if(json->tokens[i+1+index].type==TOKEN_STRING && json->tokens[i+1+index].isArray==true ) return json->tokens[i+1+index].string; } } return NULL; } int getArrayCount(JSON *json, char *key) { for(int i=0; i<TOKEN_COUNT; i++) { if(json->tokens[i].type==TOKEN_STRING && strcmp(json->tokens[i].string,key)==0) { int j=0; while(json->tokens[i+1+j].isArray==true) j++; return j; } } return 0; } double getNumber(JSON *json, char *key) { for(int i=0; i<TOKEN_COUNT; i++) { if(json->tokens[i].type==TOKEN_STRING && strcmp(json->tokens[i].string,key)==0) { if(json->tokens[i+1].type==TOKEN_NUMBER) return json->tokens[i+1].number; } } return 0.0; } void freeJSON(JSON *json) { for(int i=0;i<TOKEN_COUNT; i++) { if(json->tokens[i].type == TOKEN_STRING) free(json->tokens[i].string); } } int main() { int size; char *doc = readFile("example.json",&size); if(doc == NULL) return -1; JSON json={0,}; parseJSON(doc,size,&json); printf("Title: %s\n",getString(&json,"Title")); printf("Year: %d\n",(int)getNumber(&json,"Year")); printf("Runtime: %d\n",(int)getNumber(&json,"Runtime")); printf("Genre: %s\n",getString(&json,"Genre")); printf("Director: %s\n",getString(&json,"Director")); printf("Actor: \n"); int actors = getArrayCount(&json,"Actor"); for(int i=0; i<actors; i++) printf(" %s\n",getArrayString(&json,"Actor",i)); printf("imdbRating: %f\n",getNumber(&json,"imdbRating")); freeJSON(&json); free(doc); return 0; }
어디가 틀린지 모르겠습니다..
Re: 83.8 질문입니다
, 도장_ 관리자님이 작성parseJSON 함수 호출 후에 중단점을 확인해보면
하단 자동 조사창에서 tokens에 값이 제대로 들어와 있지 않다는 것을 알 수 있습니다. Year의 값은 2010이고, double 타입이면 2010.0000...으로 값이 있어야 합니다. 따라서 파싱 단계에서 오류가 있다는 뜻입니다.
디버거 사용법은 UNIT 6을 참조해주세요.
한 단계씩 실행해보는 것도 방법입니다.
doc에 제대로 된 값이 들어오는지 확인하세요.
포럼 상단 오른쪽에서 83.8로 검색하면 이전 질문과 답변을 참조할 수 있습니다.