とーけないざー(続き

えと、仕事中に調べてたら、標準C++どころかCの関数にあったそうな。strtok()…。くそー、半日が無駄か。。。まあ、なんか微妙に使い方が判らなかったので、やっぱり自作しました。

Tokenizerつうのは、searchとは違って、デリミタと呼ばれる区切り文字(スペースとかタブとか、カンマとかでもOK)で分けられた単語を文字列から拾い上げるモジュールです。なんで、

  char str[] = "I_am_a_desk!";
  CTokenizer Token( str, "_");    // デリミタに_(アンダーバー)を指定

  char* strToken;
  while( *(strToken=Token.GetNext()) )
  {
    printf( "%s\n", strToken );
  }

とかやると、

  I
  am
  a
  desk!

とか表示されます。

以下、作ったやつ。strtok()を参考にして、入力文字列をぶっ壊す代わりにnew, deleteを廃しました。ループの中で使う関数ではないので、実行速度は大して問いませんが、メモリリークを考えるとnew, deleteしないに越したことはないですよね。


CTokenizer.h

#ifndef _TOKENIZER_H_
#define _TOKENIZER_H_

class CTokenizer
{
public:
	CTokenizer();
	CTokenizer(char* pStr, char const* pDel = NULL);

	inline void		SetString(char* pStr, char const* pDel = NULL);
	char*			GetNext();
	
private:
	inline int		IsKugiri(char Target);
	
	char*			m_pString;
	char const*		m_pDelimiter;

	static char const*	m_pDefaultDelimiter;
};

#endif

で、CTokenizer.cpp

#include "stdafx.h"
#include "CTokenizer.h"


char const* CTokenizer::m_pDefaultDelimiter = "\t ";


CTokenizer::CTokenizer()
{
	m_pString = NULL;
}

CTokenizer::CTokenizer(char* pStr, char const* pDel)
{
	SetString(pStr, pDel);
}

void CTokenizer::SetString(char* pStr, char const* pDel)
{
	m_pDelimiter = pDel ? pDel : m_pDefaultDelimiter;
	m_pString = pStr;
}

char* CTokenizer::GetNext()
{
	char* pTokenHead = m_pString;

	for( ; *m_pString; m_pString++)
	{
		if( IsKugiri(*m_pString) )
		{
			*m_pString++ = '\0';
			for( ; IsKugiri(*m_pString); m_pString++ );
			break;
		}
	}
	return pTokenHead;
}


int CTokenizer::IsKugiri(char Target)
{
	for( int cnt=0; m_pDelimiter[cnt]; cnt++ )
	{
		if( Target == m_pDelimiter[cnt] )
			return 1;
	}

	return 0;
}

ついでに、main.cpp

#include "stdio.h"
#include "stdlib.h"

#include "./src/CTokenizer.h"

int main( int argc, char** argv )
{
	char tmpStr[] = "I am  a  desk!";
	CTokenizer tmpToken( tmpStr );

	char* str;
	
	while( *(str = tmpToken.GetNext()) )
		printf("%s\n", str);

	return 0;
}