이틀 의 공백기간 후 올리는 포스팅 이군요. 퇴근시간이 약간 늦어지는 것 때문에 막상 도착하니 짧은 시간에 무엇을 할까 고심을 많이 했습니다. 최근 계속해서 알고리즘 트레이닝 북에 있는 문제를 하나씩 풀어가고 있긴 했지만 워낙 남은 시간이 짧아 조금 그렇더군요.
그래서 오늘 마침 빨리 퇴근한 김에 수정하고 있는 프로그램에서 쓰고 있는 boost::tokenizer 를 보기로 했습니다. 아주 예전 C 부터 사용하던 분들이라면 strtok 함수를 이용하여 토큰을 분리하거나, 직접 코드를 작성하여 코드를 분리하곤 했습니다. 파싱을 통한 토큰 분리를 수행해 주는 여타 클래스도 존재하긴 합니다. 그런 김에 boost::tokenizer를 보니 stl과 비슷한 방법으로 토큰 분리를 해주는 클래스를 보니 무척 반갑더군요. 그런데 문제는 하나 있었습니다. 일단 코드를 한 번 보도록 하겠습니다.
위 코드 수행시 결과는 a\nbb\rccc\nddd 입니다. \n는 뉴라인이라고 생각하시면 결과를 추측하실 수 있겠죠? 간단하게 출력을 수행하는 부분인데, 기본적인 이 방법으로는 std::string 형인 aa에 한글이 섞여있는 문자열을 적을경우 분리가 불가능하며 심지어 에러를 표시합니다. 그래서 선언을 봤는데 token_functions.hpp에 있는 seperator를 기본으로 사용하듯이 한글이나 2바이트 확장 아스키에 대해서는 추가로 seperator 클래스를 구현해주어야 하더군요.
위와 같은 클래스를 구현해주고, 해당 tokenizer에서 사용하는 TokenizerFunc Template 인자에 넣어주면 됩니다. 어차피 Template 이라는 자체가 결과적으로는 Define 치환결과하고 동일하다고 볼 수 있으니까요. 예전 strtok혹은 개별 토큰 기능을 구현하기 보다는 이런 클래스를 사용한다면 에러가 더 적게 발생하지 않을까요? 당연한 말이겠지만 이미 이런 클래스들은 여러사람이 사용하고 문제점은 이미 검증되었으니까요. 만약 이런 클래스 구현을 통한 확장 아스키 지원이 조금 걸리면 Unicode 변환 -> Tokenizing -> 확장아스키 변환 이런 방법도 있겠네요. 사실 최근 대세가 Unicode로 돌아선지 꽤 되었다 보니, 이미 Unicode 형태로 처리를 하고 있을지도 모르겠습니다. 그래도 예전에 사용했거나 필요할 때 이 글을 보면서 구현을 하면 될 듯 하군요. 그럼 오늘도 즐거운 하루 되세요..^^
정신이 약간 오락가락 하네요. 너무 놀아서 그런가 봅니다. 오늘 12시쯤 회사로 출근을 하여 웹 서핑중 boost 의 1.35 버젼 릴리즈 소식이 보이더군요. 개인적으로 엄청 좋아하는 라이브러리이다 보니 반갑기 그지 없었습니다. 자자 어떤게 업데이트 되었냐구요??
새로 추가된 라이브러리
ASIO - 소켓과 소켓 iostream 지원과, Portable Networking
Bimap - Bidirectional Map 라이브러리( Associative Container 의 하나 )
Circula Buffer - ring 혹은 Cyclic 버퍼로 알려진 STL Container
Function - 함수 포인터, 함수 레퍼런스 등..
Fusion - tuple에 적용되어 작용하는 라이브러리, tr1에서 tuple이 정식으로 승격되었죠?
GIL - 일반적인 이미지 라이브러리
Interprocess - Shared Memory, Memory Mapped File, Process-Shared Mutex.. 등등 이게 가장 눈에 띄네요?^^
Intrusive, Math/ Special Function 등 여러가지가 추가되었습니다.
업데이트 된 라이브러리
Graph
Hash
Iostreams
multiarray
Multi-Index Containers
Serialization
Thread
Wave
Xpressive
대충 살펴보니 좋은게 많이 추가된 것 같습니다. 에구 있는 것도 다 파악 못했는데, 아주 주르르륵 쏟아져 나오는군요. 조금씩 살펴보면서 적재적소에 사용을 해봐야겠습니다. 회사에서 건네받은 다른회사가 진행하고 제가 유지보수 해야 될 프로젝트 부분을 보니 std::lexical_???? 쪽 함수를 사용하더군요. 마음이 설레어 옵니다^^;
위 구문이 익숙하시죠?? 보통 C/C++을 하시다가 어떠한 난수를 발생시키고자 할 때에 한 번쯤은 써보셨을 겁니다. 그런데 실질적으로 srand 라는 부분도 문제가 되고, % 연산자로 숫자의 범위를 만들어 주어야 하는 단점이 존재합니다. 그 뿐만 아니라 rand() 함수 자체가 short 형인 65536 까지 제한이 걸리다 보니 하고 싶은 작업에 있어서도 제한이 걸립니다. 그런데 역시라고 해야 될지 boost 에는 이런 문제를 해결 해놓은 라이브러리가 존재합니다. 바로 boost::random 입니다.
간단하게 보이죠?? mt19937 같은 부분은 난수발생엔진 부분이고 uniform_int 는 범위와 데이터 형태를 정의하는 부분입니다. varitate_generator 를 이용하여 해당 엔진을 typename 으로 하여 Dice 롤링을 하죠. 그 것을 바로 std::cout 을 이용해 출력하면 콘솔에서 제대로 출력됩니다. 1 ~ 6 의 숫자가 50번 동안 난발적으로 생성됩니다. 뿐만 아니라 boost::uniform_int 대신 boost::uniform_real를 사용하면 실수가 나옵니다. @0@ 많이 편하지 않나요^^. 사용할 곳이 많이 생길지도 모르겠네요.
흔히 말하는 프로그래밍의 기본이라는 C/C++을 하지 않아도 어떠한 언어를 하다보면 배열이라는 것을 배우게 됩니다. 그런데 아시다시피 C/C++ 에서 기본 배열을 사용하게 되면 길이를 비롯해서 불편함 점이 많습니다. 그래서 보통 사람들은 std::vector 를 사용하는 경향이 있는데요. boost 에 올라와있다 TR1 표준에 포함되는 것 중에는 Array 클래스가 존재합니다. 뭐 굳이 얘길 한다면 뭐라 말할 정도로 편리해 지지는 않았지만 해당 부분에 있어서 기타 STL 알고리즘과 호환되게 하는 면이 중점적으로 다루어진것 같았습니다.
사용법은 다음과 같습니다. 헤더는 위의 boost 라이브러리가 프로젝트 인클루드 폴더에 포함되어있다는 가정하에 컴파일이 가능하며, 이 것이 begin, end 같은 부분으로 많이 편리해졌다는 것을 알 수 있습니다. 선언에서는 데이터 형태와, 크기를 넣어주어야 하죠. 물론 실질적으로 그냥 사용할 때는 [] 리터럴을 사용하는 배열과 별 다른점을 느끼지 못할지도 모르겠지만 STL 상에서 traits 들과 결합하여 사용한다면 사용법에 있어서 많은 편리함이 생길것 같습니다.
댓글을 달아 주세요