C++ 문자열 테이블 만들기 ( C++ make string table ), 문자열 파싱
txt 파일이 있고,
< id='1' color='255|10|0' text='나공간' >
< id='2' color='255|255|255' text='1476년\n고려왕조가 멸망하고, 조선왕조가 건국된지 수십년의 세월이 흘렀다.\n새 왕조는 기세를 확장하여
점차 기반을 다져가고 있었다. 그러나 백성들의 곤궁한 삶은 별로 나아진 것이 없었다.' >
....
....
이런 식으로 문자열 테이블을 관리하고 싶을 때
사용할 수 있는
간단한 문자열 파싱 소스입니다.
예제는
id, color(r,g,b), text 등을 문자열마다 지정해 두고 사용할 수 있습니다.
#define MAX_SCRIPT_LINESIZE 255
#define SCRIPTTEXT_HEADER 0xf7063dd1
#define SCRIPT_BIG_SEP "<>" //제일큰 구분자
#define SCRIPT_SMALL_SEP "=()'<>{}[]|" //.은 소수점 표현에 사용된다
//,은 텍스트에서 쉼표로 사용
#define SCRIPT_CMD( string, var ) (strstr(string,var) ? 1 : 0) //string안에 var가 있는지 찾는다
void FileLoad( const char *_pszFile )
{
//파일 열기
FILE *fp=NULL;
fopen_s( &fp, _pszFile, "rt" );
if( !fp )
{
char szMessage[200];
sprintf_s( szMessage, "CScript_Text> %s file is invalid!", _pszFile );
MessageBoxA( NULL, szMessage, "FILE LOAD", MB_OK );
return;
}
char szLine[MAX_SCRIPT_LINESIZE];
std::string STR;
STR.reserve( 1500 ); //문자열을 저장할 버퍼, 크기는 용도만큼 잡아서 사용
BYTE nType = 0;
//한 라인씩 읽어 들이면서, 각각의 문자열을 구성해 줍니다.
//테이블의 문자열 하나가 여러 라인을 사용하고 있을때는
//큰 구분자 끝이 나올때까지 문자열을 합칩니다
while( fgets(szLine, MAX_SCRIPT_LINESIZE, fp) )
{
//큰 구분자가 있는지 검색하여, 두개다 있으면 라인 하나 짜리
if( strchr( szLine, '<' ) && strchr( szLine, '>' ) )
{
nType = 0;
}
//문자열 테이블 시작
else if( strchr( szLine, '<' ) )
{
nType = 1;
}
//문자열 테이블 끝
else if( strchr( szLine, '>' ) )
{
nType = 2;
}
//큰 구분자가 없으면, 문자열 중간이 되겠지요
else
{
nType = 3;
}
switch( nType )
{
//한라인짜리
case 0:
{
STR = "";
STR = szLine;
//테이블 문자열 하나의 구성이 완료되었다면, 파싱해 줍니다.
Parse( (char*)STR.c_str(), pS );
}
break;
//라인연결
case 1:
{
STR = "";
STR += szLine;
}
break;
//라인연결끝
case 2:
{
STR += szLine;
//테이블 문자열 하나의 구성이 완료되었다면, 파싱해 줍니다.
Parse( (char*)STR.c_str(), pS );
}
break;
//라인연결중
case 3:
{
STR += szLine;
}
break;
}
fclose( fp );
}
//통짜스트링을 각각의 변수들로 파싱한다
void Parse( char* _pszBuffer, SScriptText* _pS )
{
char* pszValText = NULL;
//strtok 사용시 처음 호출때는 버퍼를 함수 인자로 넘기고,
pszValText = strtok( (char*)_pszBuffer, SCRIPT_SMALL_SEP );
while( pszValText != NULL )
{
ParseValue( pszValText, _pS );
//문자열 안을 계속 파싱할 때는 NULL 을 대입해 줍니다
pszValText = strtok( NULL, SCRIPT_SMALL_SEP );
}
}
//분리된 변수들에게서 값을 읽어 들인다
void ParseValue( char* _pszValText, SScriptText* _pS )
{
if( SCRIPT_CMD(_pszValText, "id") )
{
_pszValText = strtok( NULL, SCRIPT_SMALL_SEP );
int id = atoi(_pszValText);
}
else if( SCRIPT_CMD(_pszValText, "color") )
{
BYTE r,g,b;
_pszValText = strtok( NULL, SCRIPT_SMALL_SEP );
r = atoi(_pszValText);
_pszValText = strtok( NULL, SCRIPT_SMALL_SEP );
g = atoi(_pszValText);
_pszValText = strtok( NULL, SCRIPT_SMALL_SEP );
b = atoi(_pszValText);
}
else if( SCRIPT_CMD(_pszValText, "text") )
{
_pszValText = strtok( NULL, SCRIPT_SMALL_SEP );
}
}
strtok 를 사용하면 구분자를 넣어서,
구분자를 제외한 사이 사이의 문자열들을 추려낼 수 있습니다.
바이너리 파일로도 사용가능 하겠지요.
저장 할때는
txt 의 라인을 fwrite 를 사용해서 쭉 저장해 두고,
(단, 저장 & 읽어들일 라인의 크기는 정해두어야 합니다. )
읽을 때는
fread 를 이용해서 읽어들이면 됩니다.
파싱 부분은 어차피 char 데이타를 파싱하는 것이라,
동일하게 사용할 수 있습니다.
'프로그래밍' 카테고리의 다른 글
로그 log (0) | 2014.06.25 |
---|---|
범프매핑 노말매핑 법선매핑 (0) | 2014.06.10 |
셰이더 - 퍼 픽셀 라이팅 ( per pixel lighting ) (0) | 2014.05.12 |
BSP 트리 ( bsp tree ) - 06 (0) | 2014.04.21 |
BSP 트리 ( bsp tree ) - 05 (0) | 2014.04.21 |