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

C/C++ 팁&트릭
[13] [STL]strtok()를 대체하는, string용 토크나이저(tokenizer)의 구현
김백일 [cedar] 13139 읽음    2002-06-01 17:24
지난번 글(1, 9번)에서, string(basic_string)에는
find_first_of(), find_last_of(), find_first_not_of(), find_last_not_of()
라는 멤버함수가 있어서 토크나이저나 trim()등을 쉽게 구현할 수 있다고 했습니다.
그럼 한 번 토크나이저를 구현해보도록 하죠.

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

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

지금 소개하는 토크나이저는
strtok()나 자바의 StringTokenizer.nextToken()과 같이
토큰들을 얻기 위해 여러번 호출하는 방식이 아니라,
결과 토큰들을 아예 컨테이너에 모두 담는 구조로 만들었습니다.
또한 버퍼를 건드리지도 않고, static 변수를 쓰지도 않기 때문에,
strtok을 쓸 수 없는 경우에 모두 사용할 수 있습니다.


//---------------------------------------------------------------------------
#include <iostream>
#pragma hdrstop
#include <string>
#include <algorithm>
#include <iterator>
#include <list>

using namespace std;
//---------------------------------------------------------------------------

template <typename OutputIterator>
void tokenize(const string& text, const string& delimiters, OutputIterator first);

#pragma argsused
int main(int argc, char* argv[])
{
    string WS = "\t\n ", sentence = "This sentence contains five words.";
    list<string> sl;
    // back_inserter를 써서 내부적으로 sl.push_back()을 호출합니다.
    tokenize(sentence, WS, back_inserter(sl));
    copy(sl.begin(), sl.end(), ostream_iterator<string>(cout, "\n"));

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

template <typename OutputIterator> // 여기서 *first의 타입은 string이어야 합니다.
void tokenize(const string& text, const string& delimiters, OutputIterator first)
{
    int start, stop, n = text.length();

    for(start = text.find_first_not_of(delimiters);
        0 <= start && start < n;
        start = text.find_first_not_of(delimiters, stop + 1)) {
        stop = text.find_first_of(delimiters, start);
        if (stop < 0 || stop > n) stop = n;
        *first++ = text.substr(start, stop - start);
    }
}

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

This
sentence
contains
five
words.

+ -

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