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

C/C++ 팁&트릭
[15] [STL]Java 소스의 변환을 위해... string용 string_tokenizer
김백일 [cedar] 11802 읽음    2002-06-11 14:35
안녕하세요? 김백일입니다.

지난번(13번)글에서 string용 토크나이저를 만들 때는,
출력 반복자(Output Iterator)를 사용하여,
하나의 컨테이너에 모든 토큰을 전부 저장하는 구조로 만들었습니다.
이런 구조는 대부분의 경우에 편리하기는 하지만,
경우에 따라서는 한번의 함수 호출에, 하나의 토큰 만을 얻어오는 인터페이스도
필요할 때가 있습니다.
strtok()나 자바의 StringTokenizer 같은 경우가 그런 예이죠.
(XML을 해보신분을 아시겠지만, 이건 마치 DOM과 SAX의 차이와 비슷합니다.)

이번에는 특히, 자바에서 C++로 전향하신 분들을 위해
자바의 StringTokenizer와 비슷한 클래스를 만들어 보았습니다.

StringTokenizer는 자바를 조금이라도 해보신 분들은 다 아실만한 클래스입니다.
자세한 내용은 다음 JDK의 다큐먼트를 참고하세요.
http://java.sun.com/j2se/1.4/docs/api/java/util/StringTokenizer.html

저는 이 StringTokenizer의 구조에 대해 한가지 불만이 있는데요,
토큰과 구분자(delimiter)를 얻는 인터페이스를 다르게하지 않고,
StringTokenizer 생성자의 인자인 returnDelims를 true로 하여
토큰과 구분자의 구별이 없이 리턴받는 점입니다.
리턴받은 다음에 if문으로 다시 검사를 해야하는 귀찮은 점이 있지요.
(물론 지난번 글의 토크나이저는 구분자를 아예 리턴하지도 않았지만요.
이유는? 단지 귀찮아서... -_-;;)

그래서 이번에 올리는 string용 string_tokenizer의 인터페이스는
자바의 것과 이부분의 인터페이스를 다르게 구현했습니다.
자바 소스에서 변환하실 때 이부분만 유의해서 보시면 되겠습니다.


const string default_delim("\t\v\f\r\n ");

class string_tokenizer
{
public:
    string_tokenizer(string str)
        : Str(str), N(str.length()), Delim(default_delim), Start(0), Stop(-1) {}
    string_tokenizer(string str, string delim)
        : Str(str), N(str.length()), Delim(delim), Start(0), Stop(-1) {}

    int count_tokens() const;

    bool has_more_tokens();

    char next_token(string& token, string delim);
       char next_token(string& token) { return next_token(token, Delim); }
protected:
    string Str, Delim;
         int Start, Stop, N;
};

inline bool string_tokenizer::has_more_tokens()
{
    Start = Stop < 0 ? Str.find_first_not_of(Delim) :
            Str.find_first_not_of(Delim, Stop + 1);
    Stop = Str.find_first_of(Delim, Start);
    return 0 <= Start && Start < N;
}

// 이 부분이 자바와 다릅니다.
// 토큰은 이 함수의 token 인자로 출력하고,
// 구분자는 리턴값으로 출력합니다.
// 이렇게 하는 것이 훨씬 이해하고 쉽고 편리하지요.
char string_tokenizer::next_token(string& token, string Delim)
{
    char cRet;

    if (Stop < 0 || Stop > N) {
        Stop = N;
        cRet = '\0';
    } else {
        cRet = Str[Stop];
    }
    token = Str.substr(Start, Stop - Start);
    return cRet;
}

int string_tokenizer::count_tokens() const
{
    int start, stop, count = 0;

    for(start = Str.find_first_not_of(Delim);
        0 <= start && start < N;
        start = Str.find_first_not_of(Delim, stop + 1)) {
        stop = Str.find_first_of(Delim, start);
        if (stop < 0 || stop > N) stop = N;
        count++;
    }

    return count;
}


#pragma argsused
int main(int argc, char* argv[])
{
    string token, sentence = "This sentence contains five words.";
    char retDelim;
    string_tokenizer st(sentence);
    cout << st.count_tokens() << endl;
    while (st.has_more_tokens()) {
        retDelim = st.next_token(token);
        cout << token << " \"" << retDelim << "\"" << endl;
    }

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

+ -

관련 글 리스트
15 [STL]Java 소스의 변환을 위해... string용 string_tokenizer 김백일 11802 2002/06/11
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.