본문 바로가기

Robotics/Software Tech.

[STL] string tokenizer


이전에 boost 라이브러리를 사용해서 stirng tokenizer를 만드는 방법을 간단하게 이야기 했었다.
이번에는 STL을 사용해서 string tokenizer를 만든 예를 올려본다.
이 클래스를 기반으로 text형태의 파일을 처리하는데 이용할 수 있을것이다.
소스를 올려봅니다.
그리고, 간단한 사용예를 보여드리겠습니다.


 stringTokenizer.cpp

 #include "stdafx.h"
#include "StringTokenizer.h"

stringTokenizer::stringTokenizer(const string& inputstring, const string& seperator)
: _input(inputstring), _delimiter(seperator)
{
 split();
}

size_t stringTokenizer::countTokens()
{
 return token.size();
}

bool stringTokenizer::hasMoreTokens()
{
 return index!=token.end();
}

string stringTokenizer::nextToken()
{
 if(index!= token.end()) return *(index++);
 else return "";
}

void stringTokenizer::split()
{
 string::size_type lastPos = _input.find_first_not_of(_delimiter, 0); //구분자가 나타나지 않는 위치
 string::size_type Pos = _input.find_first_of(_delimiter, lastPos); //구분자가 나타나는 위치

 while(string::npos!=Pos || string::npos!=lastPos)
 {
  token.push_back(_input.substr(lastPos, Pos-lastPos));
  lastPos = _input.find_first_not_of(_delimiter, Pos); //구분자가 나타나지 않는 위치
  Pos = _input.find_first_of(_delimiter, lastPos); //구분자가 나타나는 위치
 }

 index = token.begin();
}


 stringTokenizer.h

 #ifndef stringTokenize_h
#define stringTokenize_h
#pragma once

#include <vector>
#include <string>

using namespace std;

class stringTokenizer
{
public:
 stringTokenizer(const string& inputstring, const string& seperator);
 virtual ~stringTokenizer() {};

private:
 string _input;
 string _delimiter;
 vector<string> token;
 vector<string>::iterator index;

public:
 size_t countTokens(); //token 갯수
 bool hasMoreTokens(); //token 존재 확인
 string nextToken();  //다음 token
 void split();   //string을 seperator로 나눠서 vector에 저장
};

#endif


 example
 파일내 문자열을 분리시켜 그 데이터를 메모리에 가지고 있도록 하기위한 예제코드
 
 mapReader.h

 #pragma once

#include <string>
#include <vector>
using namespace std;

class mapReader
{
public:
 mapReader(const char* filepath);
 virtual ~mapReader(void);


public:
 void readFile(const char* filepath);

public:
 vector<vector<string>> mapData;
};


 mapReader.cpp

 #include "StdAfx.h"
#include "mapReader.h"
#include "StringTokenizer.h"

#include <fstream>

mapReader::mapReader(const char* filepath)
{
 readFile(filepath);
}

mapReader::~mapReader(void)
{
}

#define MAX_STRING_LEN 1024
void mapReader::readFile(const char* filepath)
{
 ifstream file;
 char tmpstring[MAX_STRING_LEN];
 vector<string> data;
 
 file.open(filepath);
 if(file.is_open())
 {
  while(file.getline(tmpstring, MAX_STRING_LEN))
  {
   stringTokenizer *pstringTokenizer = new stringTokenizer(tmpstring, " \t\n");
   memset(tmpstring, 0, sizeof(tmpstring));
   data.clear();

   while(pstringTokenizer->hasMoreTokens())
   {
    data.push_back(pstringTokenizer->nextToken());
   }
   if(data.size()!=0) mapData.push_back(data);
   delete pstringTokenizer;
  }
 }

 return;
}


 sample.txt
1 안녕하세요.
2 반갑습니다.
3 안녕히가세요

위 sample.txt파일을 파싱하여 그 정보를 mapData라는 곳에 저장하려면,

mapReader *pReader = new mapReader("sample.txt");

이런식으로 파일위치만 생성인자로 넘겨주면 그 정보를  mapReader의 클래스의  mapData가 파싱된 정보를 가지고 있는것이다.