== [OurMajorLangIsCAndCPlusPlus/XML/조현태] == === 느낀점 및 반성 === * C...C++이랑 많이 다르구나~ @.@ const, bool형이 없고 형체크가 정확하지 않아서 조마조마 했다는..ㅎㅎ * 테스트의 편의를 위해서 파일입출력을 안썼습니다.^^ ... 이편이 더 불편하려나?? 파입입출력으로 바꿀까..말까.. * 가독성을 위해서.... 여러파일로 나누려다 말았습니다..T.T * C와 C++의 주석 형식의 차이로 인해서... 주석이 많이 줄었습니다.^^ === 소스코드 === {{{~cpp #include #include #include typedef unsigned int bool; #define FALSE 0 #define TRUE 1 #define INPUT_BUFFUR 255 typedef struct StructReadBlock { char* name; char* contents; int nextBlockNumber; bool isOneTable; struct StructReadBlock** nextBlocks; }SReadBlock; const char DEBUG_TEXT[] = "\n \n \n 이상규\n \n 김상섭\n 김민경\n 송수생\n 조현태\n \n \n \n 이선호\n \n 김민경\n 송수생\n 조현태\n \n \n \n \n \n \n\n"; SReadBlock* CreateNewBlock(const char* name, const char* contents) { SReadBlock* newBlock = (SReadBlock*)malloc(sizeof(SReadBlock)); if (NULL == name) newBlock->name = NULL; else { newBlock->name = (char*)malloc(sizeof(char) * (strlen(name) + 1)); strcpy(newBlock->name, name); } if (NULL == contents) newBlock->contents = NULL; else { newBlock->contents = (char*)malloc(sizeof(char) * (strlen(contents) + 1)); strcpy(newBlock->contents, contents); } newBlock->nextBlockNumber = 0; newBlock->nextBlocks = NULL; newBlock->isOneTable = FALSE; return newBlock; } void AddNewTail(SReadBlock* head, SReadBlock* tail) { if (NULL != head) { SReadBlock** newNextBlocks = (SReadBlock**)malloc(sizeof(SReadBlock*) * (head->nextBlockNumber + 1)); memcpy(newNextBlocks, head->nextBlocks, sizeof(SReadBlock*) * head->nextBlockNumber); newNextBlocks[head->nextBlockNumber] = tail; free(head->nextBlocks); head->nextBlocks = newNextBlocks; ++head->nextBlockNumber; } } const char* CreateTree(SReadBlock* headBlock, const char* readData) { SReadBlock* myPoint = NULL; while(0 != *readData) { if ('<' == *readData) { ++readData; if ('/' == *readData) { readData = strchr(readData, '>'); ++readData; break; } else if (NULL == myPoint) { const char* nameEndPoint = strchr(readData, '>'); char* textBuffur = (char*)malloc(sizeof(char) * (nameEndPoint - readData + 1)); strncpy(textBuffur, readData, nameEndPoint - readData); textBuffur[nameEndPoint - readData] = 0; myPoint = CreateNewBlock(textBuffur, NULL); AddNewTail(headBlock, myPoint); free(textBuffur); if ('/' == myPoint->name[strlen(myPoint->name) - 1]) { myPoint->name[strlen(myPoint->name) - 1] = 0; myPoint->isOneTable = TRUE; return nameEndPoint + 1; } readData = CreateTree(myPoint, nameEndPoint + 1); } else readData = CreateTree(myPoint, --readData); } else { if (' ' == *readData || '\n' == *readData) { while(' ' == *readData || '\n' == *readData) ++readData; } else { const char* contentsEndPoint = strchr(readData, '<'); char* textBuffur = (char*)malloc(sizeof(char) * (contentsEndPoint - readData + 1)); strncpy(textBuffur, readData, contentsEndPoint - readData); textBuffur[contentsEndPoint - readData] = 0; myPoint = CreateNewBlock(NULL, textBuffur); AddNewTail(headBlock, myPoint); free(textBuffur); return contentsEndPoint; } } } return readData; } void ShowTree(SReadBlock* showBlock, int tabCount, bool* isLastContents) { int i = 0; /* 일반 명령어의 출력 */ if (NULL != showBlock->name) { *isLastContents = FALSE; printf("\n"); for (i = 0; i < tabCount; ++i) printf("\t"); /* 단일 항목인가 아닌가. */ if (showBlock->isOneTable) { printf("<%s/>\n", showBlock->name); } else { printf("<%s>", showBlock->name); for (i = 0; i < showBlock->nextBlockNumber; ++i) ShowTree(showBlock->nextBlocks[i], tabCount + 1, isLastContents); if (FALSE == *isLastContents) { printf("\n"); for (i = 0; i < tabCount; ++i) printf("\t"); } printf("", showBlock->name); } } /* 내용의 출력 */ else if (NULL != showBlock->contents) { *isLastContents = TRUE; printf("%s", showBlock->contents); } /* 단순한 연결의 경우 */ else { *isLastContents = FALSE; for (i = 0; i < showBlock->nextBlockNumber; ++i) ShowTree(showBlock->nextBlocks[i], tabCount, isLastContents); } } void SuchAllSameNamePoint(const char* name, SReadBlock* suchBlock, SReadBlock*** suchedBlocks) { int i = 0; SReadBlock** newBlocks = NULL; for (i = 0; i < suchBlock->nextBlockNumber; ++i) { if (NULL != suchBlock->nextBlocks[i]->name && 0 == strcmp(suchBlock->nextBlocks[i]->name, name)) { /* 새로 검색된 내용을 추가합니다. */ newBlocks = (SReadBlock**)malloc(sizeof(SReadBlock*) * ((int)(**suchedBlocks) + 2)); memcpy(newBlocks, *suchedBlocks, sizeof(SReadBlock*) * ((int)(**suchedBlocks) + 1)); *newBlocks = (SReadBlock*)(((int)**suchedBlocks) + 1); newBlocks[(int)(*newBlocks)] = suchBlock->nextBlocks[i]; free(*suchedBlocks); *suchedBlocks = newBlocks; } } for (i = 0; i < suchBlock->nextBlockNumber; ++i) { SuchAllSameNamePoint(name, suchBlock->nextBlocks[i], suchedBlocks); } } void printSuchPoints(const char* query, SReadBlock* suchBlock) { int i = 0; bool isLastContents = FALSE; const char* suchEndPoint = NULL; char* textBuffur = NULL; SReadBlock** suchedBlocks = NULL; if (0 == *query) { ShowTree(suchBlock, 0, &isLastContents); } else if ('/' == *query) { /* 단어의 끝을 찾습니다. */ query = query + 1; suchEndPoint = strchr(query + 1, '/'); if (NULL == suchEndPoint) suchEndPoint = query + strlen(query); if ('/' == *query) { query = query + 1; suchedBlocks = (SReadBlock**)malloc(sizeof(SReadBlock*)); *suchedBlocks = (SReadBlock*)0; textBuffur = (char*)malloc(sizeof(char) * (suchEndPoint - query + 1)); strncpy(textBuffur, query, suchEndPoint - query); textBuffur[suchEndPoint - query] = 0; SuchAllSameNamePoint(textBuffur, suchBlock, &suchedBlocks); free(textBuffur); for (i = 0; i < (int)(*suchedBlocks); ++i) printSuchPoints(suchEndPoint, suchedBlocks[i + 1]); } else { for (i = 0; i < suchBlock->nextBlockNumber; ++i) { if (0 == strncmp(suchBlock->nextBlocks[i]->name, query, suchEndPoint - query - 1)) printSuchPoints(suchEndPoint, suchBlock->nextBlocks[i]); } } } } void FreeMyMemorys(SReadBlock* suchBlock) { int i = 0; for ( ; i < suchBlock->nextBlockNumber; ++i) { FreeMyMemorys(suchBlock->nextBlocks[i]); free(suchBlock->nextBlocks[i]); } free(suchBlock->name); free(suchBlock->contents); } void main() { const char* readData = DEBUG_TEXT; SReadBlock* rootBlock = CreateNewBlock(NULL, NULL); const char query[INPUT_BUFFUR]; bool isLastContents = FALSE; printf("쿼리문을 입력하세요.\n>>"); scanf("%s", query); CreateTree(rootBlock, readData); if (NULL != strchr(query, '/')) { if (0 == strncmp((*(rootBlock->nextBlocks))->name, query, strchr(query, '/') - query - 1)) { printSuchPoints(strchr(query, '/'), *(rootBlock->nextBlocks)); } } else { if (0 == strcmp(query, (*(rootBlock->nextBlocks))->name)) { ShowTree(rootBlock, 0, &isLastContents); } } FreeMyMemorys(rootBlock); printf("\n"); system("PAUSE"); } }}} ---- [OurMajorLangIsCAndCPlusPlus] [OurMajorLangIsCAndCPlusPlus/XML]