U E D R , A S I H C RSS

Our Major Lang IsCAndCPlus Plus/XML/조현태

느낀점 및 반성

  • C...C++이랑 많이 다르구나~ @.@ const, bool형이 없고 형체크가 정확하지 않아서 조마조마 했다는..ㅎㅎ
  • 테스트의 편의를 위해서 파일입출력을 안썼습니다.^^ ... 이편이 더 불편하려나?? 파입입출력으로 바꿀까..말까..
  • 가독성을 위해서.... 여러파일로 나누려다 말았습니다..T.T
  • C와 C++의 주석 형식의 차이로 인해서... 주석이 많이 줄었습니다.^^

소스코드


~cpp
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

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[] = "<zeropage>\n   <studies>\n      <cpp>\n         이상규\n         <participants>\n            <name>김상섭</name>\n            <name>김민경</name>\n            <name>송수생</name>\n            <name>조현태</name>\n         </participants>\n      </cpp>\n      <java>\n         이선호\n         <participants>\n            <name>김민경</name>\n            <name>송수생</name>\n            <name>조현태</name>\n         </participants>\n      </java>\n      <mfc>\n         <participants/>\n      </mfc>\n   </studies>\n</zeropage>\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("</%s>", 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");
}
Valid XHTML 1.0! Valid CSS! powered by MoniWiki
last modified 2009-05-27 07:09:18
Processing time 0.0879 sec