간단한 파싱처리를 해야하는데, 막상 문자열 일일히 비교하기란 귀찮기 짝이 없는 작업입니다. 이를 실행하기 위한 몇가지 방법들을 찾아보았습니다.
strtok() #
표준 C 함수인데다가 쓰기도 쉽습니다. 가장 무난하지만 다음과 같은 단점이 있습니다.
- strtok() 파싱중에 다시 strtok()을 호출하면 파싱이 엉클어지더군요. (아무래도 내부 버퍼를 공유해서 생기는 버그인듯)
- c 함수인지라 매번 char[] 배열을 선언해주어야합니다.
- 파싱대상이 되는 char * 배열의 내용을 수정하므로 DLL 함수와 같은데서 반환한 const char *에 strtok()을 실행하면 보호오류가 발생하더군요.
boost::tokenizer #
boost를 사용한다면 같이 활용할 수 있는 라이브러리인데 다음과 같은 단점이 있습니다.
- 당연하지만 boost가 필요합니다! 간단한 프로젝트에는 적용하는데 귀차니즘을 불러일으킬 수도...
- 간혹 첫번째 토큰을 분석못하는 버그가 있습니다. (이때문에 사용하지 않고 있습니다)
- 템플릿 기반이라 실행화일 용량을 크게 만듭니다.
Tokenize #
http://linuxselfhelp.com/HOWTO/C++Programming-HOWTO-7.html에서 우연히 발견한 루틴입니다. 꽤 깔끔하고 뭐니뭐니해도 표준 C++ 기반이라 별도의 라이브러리도 필요없습니다.
가장 좋은 방법으로 생각합니다. 아래 함수를 선언해놓고 감사히 사용합니다.
void Tokenize(const string& str, vector<string>& tokens, const string& delimiters = " ")
{
// 처음에 나와있는 구분자들을 건너뜁니다.
string::size_type lastPos = str.find_first_not_of(delimiters, 0);
// 첫번째 "구분자가 아닌 문자"를 찾습니다.
string::size_type pos = str.find_first_of(delimiters, lastPos);
while (string::npos != pos || string::npos != lastPos)
{
// 토큰을 찾았으면 이것을 vector에 추가합니다.
tokens.push_back(str.substr(lastPos, pos - lastPos));
// 구분자를 건너뜁니다. "not_of"에 주목하세요.
lastPos = str.find_first_not_of(delimiters, pos);
// 그다음 "구분자가 아닌 문자"를 찾습니다.
pos = str.find_first_of(delimiters, lastPos);
}
}








