지난번 강의 에 이어 오늘 포스트할 내용은 기본 분리에 다시 상세 분리를 하여
만들어 놓은 구조체에 담아 저장후 출력하는것으로 이어 가겠습니다.
지난번 강의는 아래 링크로 확인해 주세요.
소스를 보기 전에 처리 하는 방법을 설명 드리고 시작 하겠습니다.
문자열을 파싱하여 담을 구조체를 설계합니다. 저는 아래와 같이 구조체로 설계 했습니다.
struct _BlogPostInfo { char szTitle[60]; char szID[20]; char szDate[10]; };
그리고 개별 아이템을 분리하여 구조체에 담는 처리를 하기 위해서 별도 함수를 작성하여 활용 했습니다.
함수 원형은 아래와 같으며 나머지는 동작한는 소스를 확인한후 설명을 이어가도록 하겠습니다.
void doParseItem(char* szItem, struct _BlogPostInfo* pItem)
아 추가로 C언어 에서는 기본적으로 min, max 함수를 지원하지 않으므로 직접 매크로로 제작하여 사용합니다.
기본적인 C언어 3항 연산자를 활용하여 구현 했으니 소스를 보시면 알수 있을거 같네요.
#include <stdio.h> #include <string.h> #ifndef max #define max(a,b) (((a) > (b)) ? (a) : (b)) #endif #ifndef min #define min(a,b) (((a) < (b)) ? (a) : (b)) #endif struct _BlogPostInfo { char szTitle[60]; char szID[20]; char szDate[10]; }; void doParseItem(char* szItem, struct _BlogPostInfo* pItem) { int nItemLen = strlen(szItem), nIdx, nSTItem=0; char szKey[128]={0}, szValue[128]={0}; for (nIdx = 0; nIdx < nItemLen; nIdx++) { if (szItem[nIdx] == '=') { strncpy(szKey, szItem, nIdx); nSTItem = nIdx+1; } } strncpy(szValue, szItem+nSTItem, nItemLen-nSTItem); if (strcmp(szKey, "Title") == 0) { strncpy(pItem->szTitle, szValue, min(strlen(szValue), sizeof(pItem->szTitle))); } else if (strcmp(szKey, "Writer") == 0) { strncpy(pItem->szID, szValue, min(strlen(szValue), sizeof(pItem->szID))); } else if (strcmp(szKey, "PostDate") == 0) { strncpy(pItem->szDate, szValue, min(strlen(szValue), sizeof(pItem->szDate))); } } void main() { char* sOrgSrc = "Title=Blog@Writer=Berdo@PostDate=20220120"; struct _BlogPostInfo postItem; memset(&postItem, 0x00, sizeof(struct _BlogPostInfo)); //일반 구문으로 아이템 분리. int nOrgSrcLen = strlen(sOrgSrc); int nSTItem=0, nIdx=0; char szPrt[128]={0}; for (nIdx = 0; nIdx < nOrgSrcLen; nIdx++) { if (sOrgSrc[nIdx] == '@') { strncpy(szPrt, sOrgSrc+nSTItem, nIdx-nSTItem); doParseItem(szPrt, &postItem); memset(szPrt, 0x00, 128); nSTItem = nIdx+1; } } //마지막항목 출력. strncpy(szPrt, sOrgSrc+nSTItem, nOrgSrcLen-nSTItem); doParseItem(szPrt, &postItem); printf("==============================\n"); printf("BlogItem Title: %s\n", postItem.szTitle); printf("BlogItem Writer: %s\n", postItem.szID); printf("BlogItem Date: %s\n", postItem.szDate); printf("==============================\n"); }
소스를 리딩하는것은 함수먼저 보는것이 아니라 시작되는 프로그램부터 보면서 안쪽으로 분석 하시는 방법으로 하는것을 추천 드립니다.
위 소스의 시작은 main 함수 입니다.
기존에 구현한 함수와는 별차이가 없고 추가된것은 구조체 선언한 변수 postItem 가 들어가 있습니다.
'@' 문자열로 파싱한 아이템을 넘겨서 postItem 에 개별 담기를 하기 위해서 doParseItem 함수가 호출된것을 볼수 있습니다.
doParseItem 함수는 'Key=Value' 형태로 넘어오는 문자열을 파싱하여 구조체에 원하는 항목으로 집어넣는 과정입니다.
함수 시작과 함께 for 문과 마지막항목 분리로 Key와 Value 값을 추출한후
마지막에 Key 값에 따라 구조체 항목에 집어 넣는 과정으로 분류 됩니다.
일련의 과정이 끝나고 나면 마지막에 구조체 항목을 상세히 출력하여 온전하게 분리된 문자열 데이터를 보실수 있습니다.
두번쨰 코드는 strstr을 사용하여 분리 하는 과정이고 소스의 형태는 위와 큰차이가 없습니다.
strstr 을 써서 문자열 기본 파싱하는것은 기존 강의를 참조 하시면 될거 같아요.
#include <stdio.h> #include <string.h> #ifndef max #define max(a,b) (((a) > (b)) ? (a) : (b)) #endif #ifndef min #define min(a,b) (((a) < (b)) ? (a) : (b)) #endif struct _BlogPostInfo { char szTitle[60]; char szID[20]; char szDate[10]; }; void doParseItem(char* szItem, struct _BlogPostInfo* pItem) { int nItemLen = strlen(szItem), nLen, nSTPos=0; char szKey[128]={0}, szValue[128]={0}; while (1) { char* pFind = strstr(szItem+nSTPos, "="); if (pFind != NULL) { nLen = pFind - (szItem+nSTPos); strncpy(szKey, szItem+nSTPos, nLen); nSTPos += nLen + 1; } else { strncpy(szValue, szItem+nSTPos, strlen(szItem) - nSTPos); break; } } if (strcmp(szKey, "Title") == 0) { strncpy(pItem->szTitle, szValue, min(strlen(szValue), sizeof(pItem->szTitle))); } else if (strcmp(szKey, "Writer") == 0) { strncpy(pItem->szID, szValue, min(strlen(szValue), sizeof(pItem->szID))); } else if (strcmp(szKey, "PostDate") == 0) { strncpy(pItem->szDate, szValue, min(strlen(szValue), sizeof(pItem->szDate))); } } void main() { char* sOrgSrc = "Title=Blog@Writer=Berdo@PostDate=20220120"; struct _BlogPostInfo postItem; memset(&postItem, 0x00, sizeof(struct _BlogPostInfo)); //strstr 을 사용하여 아이템 분리. int nSTPos = 0, nLen; char szPrt[128]={0}; while (1) { char* pFind = strstr(sOrgSrc+nSTPos, "@"); if (pFind != NULL) { nLen = pFind - (sOrgSrc+nSTPos); strncpy(szPrt, sOrgSrc+nSTPos, nLen); doParseItem(szPrt, &postItem); memset(szPrt, 0x00, 128); nSTPos += nLen + 1; } else { strncpy(szPrt, sOrgSrc+nSTPos, strlen(sOrgSrc) - nSTPos); doParseItem(szPrt, &postItem); break; } } printf("==============================\n"); printf("BlogItem Title: %s\n", postItem.szTitle); printf("BlogItem Writer: %s\n", postItem.szID); printf("BlogItem Date: %s\n", postItem.szDate); printf("==============================\n"); }
댓글 없음:
댓글 쓰기