C++Builder Programming Forum
C++Builder  |  Delphi  |  FireMonkey  |  C/C++  |  Free Pascal  |  Firebird
볼랜드포럼 BorlandForum
 경고! 게시물 작성자의 사전 허락없는 메일주소 추출행위 절대 금지
C++빌더 포럼
Q & A
FAQ
팁&트릭
강좌/문서
자료실
컴포넌트/라이브러리
메신저 프로젝트
볼랜드포럼 홈
헤드라인 뉴스
IT 뉴스
공지사항
자유게시판
해피 브레이크
공동 프로젝트
구인/구직
회원 장터
건의사항
운영진 게시판
회원 메뉴
북마크
볼랜드포럼 광고 모집

C++빌더 팁&트릭
C++Builder Programming Tip&Tricks
[342] strtok()를 대체하는, AnsiString용 토크나이저(tokenizer)의 구현
김백일 [cedar] 8271 읽음    2002-06-01 17:06
AnsiString 관련 두번째 팁입니다.

앞에 글에서
FirstDelimiter(), FirstNotDelimiter(), LastDelimiter(), LastNotDelimiter()
를 구현했으니까,
이 함수들을 사용해서 토크나이저를 구현해보도록 하죠.

"근데 왜 토크나이저를 따로 만들죠? strtok()이 있잖아요?"
라고 생각하시는 분도 있으실 겁니다.

C 표준 라이브러리에 있는 strtok()은 사용하기에는 직관적이지만,
문자열 버퍼의 내용을 건드리기 때문에
원래의 문자열 버퍼의 내용을 유지하고자 하려면 백업버퍼를 하나 더 두어야 하는 불편함이 있고,
동작시 내부적으로 static 변수를 사용하기 때문에
이중 루프 같은데에서 겹쳐서 호출하거나, 멀티스레딩에서 에러가 생기는 결정적인 단점이 있습니다.

지금 소개하는 토크나이저는
strtok()나 자바의 StringTokenizer.nextToken()과 같이
토큰들을 얻기 위해 여러번 호출하는 방식이 아니라,
결과 토큰들을 아예 TStrings 객체에 모두 담는 구조로 만들었습니다.
TStrings는 TMemo::Lines 나 TListBox::Items 등
VCL의 여러 곳에서 자주 사용되기 때문에 상당히 유용할 겁니다.
또한 버퍼를 건드리지도 않고, static 변수를 쓰지도 않기 때문에,
strtok을 쓸 수 없는 경우에 모두 사용할 수 있습니다.


예제 코드는 다음과 같습니다.
여기서는 TStrings의 자손인 TStringList 객체에 토큰을 저장하는 예제입니다.
(TStrings 단독으로는 인스턴스를 만들 수 없기 때문입니다.)

//---------------------------------------------------------------------------
// ostream& operator << (ostream& os, const AnsiString& arg) 를 쓰려면
// vcl.h보다 먼저 인클루드해야 합니다.
#include 
#include 

//
// 중략: 앞글에 있는 FirstDelimiter(), FirstNotDelimiter() 정의가 있어야 합니다.
//

void Tokenize(const AnsiString& text, const AnsiString& delimiters, TStrings* words)
{
    words->Clear();
    int start, stop, n = text.Length();

    for(start = FirstNotDelimiter(delimiters, text);
        1 <= start && start <= n;
        start = FirstNotDelimiter(delimiters, stop + 1, text)) {
        stop = FirstDelimiter(delimiters, start, text);
        if (stop < 1 || stop > n + 1) stop = n;
        words->Add(text.SubString(start, stop - start));
    }
}
//---------------------------------------------------------------------------

#pragma argsused
int main(int argc, char* argv[])
{
    AnsiString WS = "\t\n ", sentence = "This sentence contains five words.";

    TStringList *sl = new TStringList;
    try {
	Tokenize(sentence, WS, sl);
	cout << sl->Text;
    }
    __finally { // TStringList를 쓸 때는 이렇게 try ... __finally로 예외처리를 해주세요.
    	delete sl;
    }

    return 0;
}
//---------------------------------------------------------------------------

물론 출력 결과는 다음과 같습니다.

This
sentence
contains
five
words.

+ -

관련 글 리스트
342 strtok()를 대체하는, AnsiString용 토크나이저(tokenizer)의 구현 김백일 8271 2002/06/01
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.