티스토리 툴바

시간을 기록하다

블로그 이미지
by 기록자
  • 28,673Total hit
  • 6Today hit
  • 9Yesterday hit

'프로그래밍 팁'에 해당되는 글 13건

  1. 2009/06/06
    정규표현식(Regular Expression)을 이용한 Parsing Tip (1)
  2. 2009/05/20
    egrep 정규표현식 메타문자
  3. 2009/05/15
    grep 명령어 옵션
  4. 2009/05/14
    리눅스 정규표현식과 메타문자
  5. 2009/03/07
    intel icc 컴파일러를 이용한 멀티프로세스 컴파일하기
  6. 2009/03/07
    유니코드와 인코딩 방식
  7. 2009/03/07
    STL에서 컨테이너 멤버함수인 size() 사용시 간단한 팁
  8. 2008/08/31
    boost 설치
  9. 2008/08/29
    type redefinition 해결법 (2)
  10. 2008/08/19
    CString 을 std::string 으로 바꾸기
요즘 나는 업무상 필요에 의해서 perl을 공부하고 있다.
내가 생각하는 perl 의 장점은 간단한 코딩 몇 줄만으로도 상당한 위력을 발휘한다는 것이다.
그런 생각의 중심에는 바로 정규표현식이 있다.
사실 정규표현식을 사용할 수 있는 프로그래밍 언어는 여러가지 있지만, perl처럼 스크립트의 형식으로 사용하는 것에는 여러가지 장점이 있다고 생각한다.

오늘은 perl을 이용한 텍스트의 Parsing 에서 유용하게 활용할 수 있는 팁을 기록한다.

인터넷에는 수많은 문서들이 존재하며 그런 문서들을 수집하다보면 html 파일처럼 태그가 붙어 있는 문서들이 많이 있다.
오늘은 그러한 태그를 이용해 필요한 데이터를 추출할 때 사용할 수 있는 팁으로써 중첩된 동일한 태그에서 가장 안쪽의 데이터를 추출하는 방법이다.
사실 별것 아닌 방법이지만 어느날인가 KLDP에서 이 부분에 대해 해법을 찾지못하고 여러사람들이 방법들을 얘기하던 기억이 나서 적어두고자한다.

우선 아래의 예를 보면 두 개의 div 태그 안에 쌓여 있는 형태를 볼 수 있을 것이다.

aaa<div>bbb<div>123</div>ccc</div>ddd

위와 같은 경우 <div> 와 </div> 사이의 데이터를 찾고자 했을 때 다음과 같은 정규표현식을 사용할 수 있을 것이다.

/\<div\>.*?\<\/div\>/


하지만 위와 같은 형태로 데이터를 추출하면 아래와 같은 결과가 나온다

<div>bbb<div>123</div>

정규표현식의 처리 특성상 먼저 나타난 <div> 에 대해 위치를 찾아버리므로 당연한 결과이다.
하지만 우리가 원하는 데이터가 <div>123</div> 로써 태그의 형태상 가장 안쪽에 있는 것을 찾기 원한다면 어떻게 해야 할 것인가를 생각하지 않을 수 없다.

이런 경우 아래와 같은 형태의 reverse 함수와 그에 맞는 역패턴을 이용하는 방법이 쓸만하다.


이런 고민을 하고 있을법한 사람이라면 위의 코드내용에 대해서는 크게 어려운것이 없으니 쉽게 이해 할 것이라 생각하고 특별히 코드에 대한 설명은 하지 않겠다.

위의 코드를 실행하면 아래 그림과 같은 결과를 확인할 수 있을 것이다.


간단하면서도 단순하고, 또한 html 이나 xml 문서와 같이 구조가 있는 문서를 처리할 때 유용하게 사용할 수 있는 방법이라고 생각한다.

PS: 내가 기억하기로는 C#에서의 정규표현식에서는 최단일치를 할 수 있는 방법이 있었던것 같은데 안쓴지 오래되서 가물가물..;;

크리에이티브 커먼즈 라이선스
Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시 2.0 대한민국 라이선스에 따라 이용하실 수 있습니다.
TRACKBACK 0 AND COMMENT 1
egrep(extended grep)은 grep 명령어의 좀더 확장된 버젼이라 할 수 있다. 다시 말하면, 좀 더 확장된 정규표현식을 메타 문자를 사용할 수 있다. 다만 grep에서 사용할 수 있었던 \{와 \{ 는 지원하지 않는다. 그러나 egrep에서 사용할 수 있는 메타 문자를 이용하면 훨씬 편리하게 정규표현식을 사용할 수 있다.


 메타문자 기능
사용 예
설명

^
행의 시작 지시자
'^love'
 love로 시작하는 모든 행과 대응

$
행의 끝 지시자
'love$'
 love로 끝나는 모든 행과 대응

.
하나의 문자와 대응
'l..e'
 l 다음에 두 글자가 나오고 e로 끝나는 문자열을 포함하는 행과 대응

*
선행 문자와 같은 문자의 0개 이상의 개수와 대응
' *love'
 0개 이상의 공백 문자 후에 love로 끝나는 문자열을 포함한 행과 대응

[ ]
[ ]사이의 문자집합 중 하나와 대응
'[Ll]ove'
 love나 Love를 포함하는 행과 대응

[^ ]
문자집합에 속하지 않는 한 문자와 대응
'[^A-KM-Z]ove'
 A와 K 사이의 범위에 포함되지 않거나, M과 Z 사이에 포함되지 않는 한 문자와 ove가 붙어 있는 문자열과 대응

+
선행문자와 같은 문자의 1개 이상의 개수와 대응
'[a-z]+ove'
 a와 z 사이의 1개 이상의 문자와 ove가 붙어있는 문자열과 대응(ex: move, love, ...)

?
선행문자와 같은 문자의 0개 혹은 1개와 대응
'lo?ve'
 l 다음에 o가 0개 혹은 1개이고 ve가 붙어있는 문자열과 대응. love 혹은 lve.

a|b
a 혹은 b와 대응
'love|hate'
 love 혹은 hate와 대응

( )
정규표현식을 묶어준다
'lov(able|ely)'
'(ov)+'
lovable 혹은 lovely와 대응
ov가 한 번 이상 등장하는 문자열과 대응

개인적으로 처음으로 정규식을 사용하게 되었던게 C#에서 문자열 처리를 해야할 때였다. C#에서는 좀더 확장된 기능을 사용할 수 있어서 편리했던 것 같다(물론 큰 차이는 없지만...). egrep에 좀 더 익숙해지면 아마도 충분히 편리하게 사용할 수 있을 것 같다.
크리에이티브 커먼즈 라이선스
Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시 2.0 대한민국 라이선스에 따라 이용하실 수 있습니다.
TRACKBACK 0 AND COMMENT 0

이번에는 지난번 리눅스 정규표현식과 메타문자에 대한 포스팅에 이어서 실제로 그러한 메타문자를 자주 사용하게 되는 grep 이라는 명령어에 대해 기록한다.
우선 grep 이라는 이름의 기원은 ex 문서 편집기에서 찾을 수 있다. ex 편집기를 사용하여 특정 문자열을 찾으려면 프롬프트에서 다음과 같이 입력하여야 한다.
: g/pattern/p
g(global)가 pattern 앞에 오면 파일의 모든 행을 검색한다. 여기서 p는 print 를 말하는 것이다. 검색 패턴을 정규표현식이라고 부르기도 하므로, pattern을 RE(regular expression)로 대신해서 명령어를 다음과 같이 표시할 수 있다.
: g/RE/p
이와같이 grep 이라는 이름의 의미만 알아도 grep 이라는 명령어가 하는 일을 대략 추측할 수 있다. grep은 정규표현식(RE)을 파일 전체(g)에서 찾아 해당 행을 출력(p)한다. grep을 쓸 때의 장점은 패턴 검색을 위해 편집기를 실행시킬 필요가 없을 뿐만 아니라, ex나 vi보다 속도가 훨씬 빠르다.

아래의 표는 grep 명령어를 사용할 때 쓰이는 몇가지 옵션들이다.


 옵션 설명

 -b  검색 결과의 각 행 앞에 검색된 위치의 블록 번호를 표시한다. 검색 내용이 디스크의 어디쯤 있는지 위치를 알아내는데 유용하다

 -c  검색 결과를 출력하는 대신, 찾아낸 행의 총수를 출력한다.

 -h  파일 이름을 출력하지 않는다.

 -i  대소문자 구분을 하지 않는다.

 -l  패턴이 존재하는 파일의 이름만 출력한다.

 -n  파일 내에서 행 번호를 함께 출력한다.

 -s  에러 메시지 외에는 출력하지 않는다. 종료 상태를 검사할 때 유용하게 쓸 수 있다.

 -v  패턴이 존재하지 않는 행만 출력한다.

 -w  패턴 표현식을 하나의 단어로 취급하여 검색한다. 즉 \< 와 \> 를 양쪽에 사용한 것과 같은 효과를 낸다. grep에서만 사용할 수 있다.


크리에이티브 커먼즈 라이선스
Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시 2.0 대한민국 라이선스에 따라 이용하실 수 있습니다.
TRACKBACK 0 AND COMMENT 0
리눅스(유닉스)의 정규표현식과 메타 문자를 기록합니다.

먼저 정규표현식이란 문자들의 패턴이라고 할 수 있습니다. 리눅스(혹은 유닉스) 시스템의 대부분의 프로그램에서 정규표현식은 슬래시 사이에 옵니다. 예를 들어 /love/ 는 /와/로 둘러쌓인 정규표현식이라 할 수 있으며, 해당 명령은 검색 시 행에서 love라는 패턴과 일치하는 것을 찾으라는 것입니다. 아래의 표는 이러한 정규표현식에 사용되는 메타 문자와 사용 예를 간단히 정리해 기록합니다.


 메타 문자
 기능  사용 예
 설명

 ^  행의 시작 지시자  /^love/  love로 시작하는 모든 행과 대응

$  행의 끝 지시자  /love$/  love로 끝나는 모든 행과 대응

.
 하나의 문자와 대응  /L..e/  L 다음에 두 글자가 나오고 e로 끝나는 문자열을 포함하는 행과 대응

 *  선행 문자와 같은 문자의 0개 혹은 임의 개수와 대응  / *love/  임의 개수의 공백 문자 후에 love로 끝나는 문자열을 포함한 행과 대응

 []  []사이의 문자 집합 중 하나와 대응  /[Ll]ove/  love나 Love를 포함하는 행과 대응

[x-y]
 []사이의 문자 범위 내의 한 문자와 대응  /[A-Z]ove/  A부터 Z까지 한 문자가 ove로 끝나는 경우와 대응

[^]
 문자 집합에 속하지 않는 한 문자와 대응 /[^A-Z]/
 A와 Z 사이의 범위에 폼함되지 않는 한문자와 대응

 \  메타 문자로 사용하고 싶지 않은 경우  /love\./  love가 마침표(.)로 끝나는 경우와 대응

 \<
단어의 시작 지시자  /\<love/  love로 시작하는 단어를 포함하는 행과 대응

 \>
 단어의 끝 지시자  /love\>/  love로 끝나는 단어를 포함하는 행과 대응

\(..\)
 다음 사용을 위해 태그를 붙인다  /\(lov\)able\1er/  9개 태그를 쓸 수 있다. 왼쪽부터 순서대로 태그 번호가 매겨진다. 예를 들어, 패턴 lov는 태그 1에 저장되고, 뒤에는 \1 로써 태그 값을 사용할 수 있다. 왼쪽 예제에서 검색 패턴은 lovable에 lover가 붙어 있는 문자열이 된다.

 x\{m\}

x\{m,\}

 x\{m,n\}

 문자 x를 m번 반복한다

 적어도 m번 반복한다

m회 이상 n회 이하 반복한다
 o\{5,10\}  문자 o가 5회에서 10회 사이의 횟수로 연속적으로 나타나는 문자열과 대응
저작자 표시
크리에이티브 커먼즈 라이선스
Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시 2.0 대한민국 라이선스에 따라 이용하실 수 있습니다.
TRACKBACK 0 AND COMMENT 0


우선 windows의 사용법이 아닌 LINUX 상에서의 사용법이며, windows에서는 icc가 아닌 icl이었던것 같다.일단 아래 링크를 따라가서 다운받자.
http://www.intel.com/cd/software/products/asmo-na/eng/340679.htm
사이트에 들어가 보면 알겠지만 인텔 컴파일러를 다운 받는 곳이다.
이곳으로 가서 비상업용 컴파일러를 받고. 받을때는 리눅스 용으로...만약 windows 사용자라면 windows 용으로 받으면 되겠다...

비상업용을 받을때는 이메일 주소 넣는게 있는데 그걸 쓰고나면 그 메일주소로 뭔가 하나 날아온다ㅋㅋㅋ
메일받고 열어보면 시리얼넘버가 쓰여져있는데 그걸 입력하거나 메일에 쓰여져있는 링크를 이용해서 사이트에 들어가면 다운받을 수 있다.

일단 다운 받으면 용량이 꽤나 큰데...내 경우엔 1G 정도되었다. 일단 다운 받은걸 압축 풀면 install.sh 파일이 있는데 이 파일을 이용해서 설치한다. 설치하던 중 내 경우에는 libstdc++5 가 안깔려 있어서 설치가 안된다길래...apt-get으로 먼저 설치하고 나서야 icc를 설치할 수 있었다.

기본적으로 설치후에는 icc 컴파일러가 어디에 설치되었는지 얘기해주는데 환경설정은 자동으로 안되는 것 같다. 그래서 나는 그냥 alias를 이용해서 사용하고 있음ㅋㅋㅋ 확인을 위해 우분투의 시스템 감시를 이용해서 cpu가 정말로 멀티로 동작되는지 확인을 위해 간단한 루프 두개를 만들어서 확인을 해보았다.


결과를 확인해보니 프로그램이 돌아가면서 계산량이 적어서인지 잠깐이지만 cpu를 나눠서 쓰고있다...오~~
(결과화면을 좀 더 그럴듯하게 보여주고 싶어서 소스코드에서 계산하는 범위를 비슷하게 바꿔서 좀 더 리얼하게 결과를 보여줘야겠다는 생각도 했으나...캡쳐하는데까지 걸리는 그 10여초의 시간이 의외로 귀찮아서 그냥 이 그림으로 올리게 되었다는....-_-;;;)

컴파일 명령은 아래와 같이 했다.

icc -openmp -o test test.c -no-multibyte-chars -static-intel

옵션 중에 -openmp 는 멀티 코어를 사용하기 위해 썼는데 프로그램 자체가 작아서 그런지 오히려 icc를 이용한 단일 코어의 속도가 더 빨리 나왔다;;; 나중에 데이터양이 큰 프로그램을 만들어서 멀티코어로 돌려봐야 좀 더 정확하게 확인 할 수 있을것 같다.

다른 옵션으로는 -no-multibyte-chars -static-intel 을 사용했는데
-no-multibyte-chars 옵션을 안쓰면 컴파일에러가 나는데 왜그런지 모르겠다.
언어권이 달라서 그런건지...유니코드를 사용하면 그런건지 확인을 못해봤다. 이 부분은 누군가가 설명해주길 바라며ㅋㅋㅋㅋ

-static-intel 은 안써도 컴파일은 되는데 안쓰면 디폴트로 공유라이브러리를 쓰는것으로 판단된다. 나는 alias로 icc만 링크해서 쓰다보니 라이브러리 링크를 제대로 못해서인지 실행하면 제대로 안돌아간다. 그래서 그냥 static library를 쓰려고 일부러 옵션을 주었다. 실제로 static 라이브러리를 사용한다고 해도 실행파일의 용량이 3~400k 정도 늘어날 뿐이기 때문에 별 문제는 없을것으로 판단된다.

ps. 어느 정도 알게됐다 생각하면 앞에 새로운 벽이 있고, 다시 그 벽을 넘어섰다 생각하면 더 높은 산이 있고...그런게 프로그래머인가보다...ㅠ_ㅠ

크리에이티브 커먼즈 라이선스
Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시 2.0 대한민국 라이선스에 따라 이용하실 수 있습니다.
TRACKBACK 0 AND COMMENT 0


요즘 리눅스에서 프로그램을 짜다보니 항상 유니코드를 염두해두지 않으면 안되게 되었다. 그리고 이제는 오히려 유니코드를 사용하게 되면서 오히려 이식성 면에서 유니코드가 얼마나 좋은지를 느껴가고 있다.

"유니코드(Unicode)는 전세계의 모든 문자를 컴퓨터에서 일관되게 표현하고 다룰 수 있도록 설계된 산업 표준이다. 유니코드협회(Unicode Consortium)가 제정하며, 최신판은 2008년 4월에 공개된 유니코드 5.1이다."

위의 내용은 위키백과에서 유니코드를 검색하면 찾을 수 있는 내용이다. 이제까지 나는 유니코드에 대해 잘못 알고있었던 것 같다. 간혹 utf-8, utf-16, ...등과 같은 것들을 들었을 때 그것들(utf-8, utf-16...등)이 유니코드 인줄 알고 있었다. 하지만 유니코드와 utf-8등은 엄연히 다른 의미이다.

유니코드라는 것이 문자들이 저장되어 있는 문자 테이블이라면 utf-8등과 같은 것들은 이 유니코드 테이블에 대한 인코딩 방법이라 할 수 있다. 예전에 아스키문자는 1바이트로 한글(완성형)과 같은 문자는 2바이트로 처리했던 기억이 있는데, 그런 이유에서인지 유니코드라 하면 그냥 단순히 2바이트라고 생각하게 되었다. 물론 나 말고도 인터넷을 검색하다보면 그렇게 생각하는 사람이 많이 있다는걸 느꼈다.

우선 유니코드의 인코딩은 utf-8, utf-16, ucs2, ucs4 등의 다양한 방식이 있다. ucs2와 utf16 계열은 모든 문자를 2바이트로 인코딩한다. 이렇게 모든 문자를 2바이트로 표시하면 영어권이나 한글, 한자, 일본어 등이 표현 가능하다. 하지만 한글 고대어 등의 2바이트 범위를 넘어가는 문자코드는 표현할 수 없게된다. 그래서 ucs4와 같이 문자를 4바이트로 인코딩하는 방법이 있는 것이다. 4바이트를 사용하면 대부분(아마도 모든 문자가 다 들어갈듯...)의 문자를 표현할 수 있지만 영어권(아스키문자만 있으면 되는) 문자를 사용하는 애들이 보기엔 엄청난 낭비가 될듯ㅋㅋㅋ(내가 시킨일이 아니야-0-)
그래서 나온것이 utf-8 인것같다. 뒤에 8이 붙어 있다고해서 1바이트(8비트)만을 사용하는 인코딩 방식은 아니며, utf-8은 가변적인 인코딩 방식이다. 즉 U+0000 ~ U+007F 까지의 문자들은 그대로 1바이트로 표기하면서(기존의 아스키 문자열도 그대로 호환), U+007F보다 큰 범위의 문자들은 그 범위에 따라 각각 2바이트, 3바이트, 4바이트로 인코딩 되는 것이다.

아래 표는 위키백과에 나와있는 표를 베껴왔습니다(꾸벅).

 Unicode 범위   UTF-8 이진표현
 U+000000-U+00007F   0xxxxxxx (1바이트 : ASCII와 동일한 범위)
 U+000080-U+0007FF   110xxxxx 10xxxxxx
 U+000800-U+00FFFF   1110xxxx 10xxxxxx 10xxxxxx (3바이트 : 한글)
 U+010000-U+10FFFF  11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

이러한 가변적인 인코딩 방식으로 낭비를 줄일 수 있고, 한글의 경우도 utf-8을 사용하면 여러가지로 이점이 있다. 특히 언어처리(NLP)를 하는 사람에게는 프로그래밍할 때 모든 문자를 유니코드로 변환한 뒤에 문자에 대한 처리를 한다면 인코딩방식에 독립적인 프로그램을 만들 수 있을 것이라 생각되며, 실제로도 그렇다.

 

크리에이티브 커먼즈 라이선스
Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시 2.0 대한민국 라이선스에 따라 이용하실 수 있습니다.
TRACKBACK 0 AND COMMENT 0

STL에서 자주 사용하게 되는 컨테이너. 그리고 그 컨테이너를 사용할 때 해당 컨테이너 안에 몇개의 원소들이 있는지 알기 위해 사용하는 size() 함수.

이제까지 별 생각없이 사용했던 size() 였으나 얼마 전에 size() 의 구현 방식을 알게되고 난 뒤로는 앞으로는 좀 더 신경써서 써야되겠다고 생각했다. "Effective STL"이라는 책에서 말하길 size의 구현 방식은 컨테이너 안의 원소에 대해 하나씩 모두 갯수를 세도록 되어 있다는 것...-0-

그 전까지는 size()의 구현이 컨테이너에 새로운 원소를 추가할 때 마다 어떤 count를 증가시키도록 되어 있어서 size() 는 단순히 그 count를 반환해 줄 것이라 생각했었는데 splice() 라는 함수와의 충돌로 인해(뭐...꼭 이것만이 아니더라도 다른 요인들도 있었겠으리라 생각되지만) 일반적으로 size()의 구현은 모든 원소의 갯수를 하나씩 세는 것으로 되어 있다는 얘기였다...OTL
뭐...결국 책에서의 얘기는 만약 size()==0 과 같은 문장을 사용할 때는 size() 대신 empty() 를 쓰라는 얘기ㅋㅋ 어찌되었건 프로그램을 짜다보면 컨테이너 안의 원소 갯수를 세어야할 경우가 생기게 되는건 어쩔 수 없는 일이고 만약 갯수가 0개인지 아닌지를 확인하기 위한 것이라면 empty()쓰라는 것이다.

물론 size()의 수행시 Associated Container(우리말로는 대부분 연관컨테이너로 번역하는듯)는 대부분 균형트리의 형태로 구현되어 있으니 O(logN)의 복잡도를 가지겠지만 List와 같은 Sequential Container(왜 이넘은 그냥 시퀀스컨테이너로 번역하는건지...차별하나??)의 경우 O(N)의 복잡도를 갖게 될 수 있다는 소리;;
뭐...데이터양이 수백~수천의 수준에 머무르는 프로그램이라면 이런건 신경쓸 필요도 없겠지만 수백만이상의 데이터를 다루게 된다면 이 차이는 확실히 프로그램 성능에 영향을 미치게 될 것 같다.
내가 여기서 뻔뜩하고 스친 생각은...이제까지 별 생각없이 써왔던 size()==0 이라는 문장이 오쉣~ 이었다는거...-_-;;

ps. 가끔씩 하드웨어가 발전하면 이런건 걱정할 것 없다고 말하는 분들이 있는데...그러면 나는 이런말을 해주고 싶다. 그런 시대가 왔을 때는 우리가 처리해야할 데이터가 수백만~수천만 수준의 단위가 아닌 수백억~수천억의 수준이면 어떻게 할거냐고...-_-;;

크리에이티브 커먼즈 라이선스
Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시 2.0 대한민국 라이선스에 따라 이용하실 수 있습니다.
TRACKBACK 0 AND COMMENT 0

C++ 프로그램을 만들다보면 정규식 라이브러리가 필요한 경우가 종종 있다.
그러나 JAVA 나 C# 같은 경우 정규식 라이브러리를 지원해 주기 때문에 쉽게 사용할 수 있지만(사실 개인적으로 자바는 겨우겨우 Hello World! 출력하는 수준이 전부이기 때문에 잘 모름) C++에서는 기본적으로 정규식 라이브러리가 지원되지 않는다. 그래서 이따금씩 정규식이 필요한 경우가 생기면 한숨부터 쉬게 된다.
사실 C++에서 정규식을 사용하려면 얼마든지 쉽게 사용할 수 있는데, 그 이유는 이미 오픈소스로 여러 라이브러리들이 만들어져 있기 때문이다. 특히 그 중에서 Boost 라이브러리는 가장 유명한 라이브러리라고 할 수 있는데, 정규식 뿐만이 아니라 프로그래머가 필요로하는 수많은 기능들이 만들어져있는 오픈소스 라이브러리이다.
항상 OS를 새로 깔고나면 이전에 설치해둔 라이브러리가 날아가버리고, 매번 필요한 경우가 생길 때마다 메뉴얼 찾아보고 인터넷 뒤져보고 설치방법 확인했었는데 이것도 은근히 귀찮은 일이었다. 그래서 오늘은 Boost 라이브러리를 설치하는 방법에 대해 기록해 두도록 해야겠다. 나중에 다시 필요한 경우가 생기면 이곳에서 바로 확인할 수 있다면 그나마 좀 덜 귀찮아 질테니 말이다.

우선 현재 내 PC 환경은
OS : Windows XP SP2
컴파일러 : Visual C++ 8.0 (Visual Studio 2005의 컴파일러 버젼이 아마 8.0 버젼이었던걸로 기억함)

그리고 이제부터 해야 할 것들
1. 먼저 Boost 를 다운받는다
http://www.boost.org/ (Boost 홈)
http://www.boost.org/users/download/ (Boost 다운로드 페이지)

2. 다운 받은 압축 파일을 풀고 컴파일한다
컴파일하는 방법에는 수동으로 컴파일하는 방법과 bjam이라는 유틸리티를 사용하는 방법이 있다.
먼저 bjam을 사용하는 방법 :
현재 나는 C:\boost_1_36_0\ 에 압축을 풀어놓은 상태이며 C:\boost_1_36_0\tools\jam\src\ 에 들어가보면 build.bat 가 있다. 이것을 실행하면 C:\boost_1_36_0\tools\jam\src\bin.ntx86\ 폴더가 생성되고 그 안에 bjam.exe 파일과 나머지 여러 오브젝트 파일들이 생성된다. 여기서 bjam.exe 파일을C:\boost_1_36_0\ 에 복사한다. 그리고 bjam.exe 를 실행하면 되는데 실행시 옵션이 주어진다. 옵션의 내용은 아래 링크를 따라가 보면 쉽게 설명이 되어 있으므로 참고하도록 한다.
http://www.boost.org/doc/tools/build/doc/html/bbv2/tutorial.html
나는 우선 커맨드 창을 열어 아래와 같이 실행해 보았다. 디폴트가 debug라고 나와있으므로 release로 만들었다.
C:\boost_1_36_0> bjam release link=static
여기서 release 는 적지 않거나 debug라고 적으면 debug 로 되고 static은 shared 로 바꿔서 적을수 있다.
튜토리얼을 살펴보면 이것저것 많이 나와있지만 이정도만 알고있으면 충분하니 넘어가도록 하자.
이렇게 하고나면 C:\boost_1_36_0\bin.v2\ 라는 폴더가 생겨나고 이곳에 이것저것 잔뜩 무엇인가가 들어가있게 된다. 물론 그 무엇인가는 바로 라이브러리들이다.

웹을 검색해보면 아래와 같이 실행하는 것도 있는데
bjam -sTOOLS="vc-8_0" --prefix="c:\boost"
이것도 한번 해봐야겠다.

크리에이티브 커먼즈 라이선스
Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시 2.0 대한민국 라이선스에 따라 이용하실 수 있습니다.
TRACKBACK 0 AND COMMENT 0
C나 C++ 프로그램을 짜다보면 이런 저런 해더 파일을 인클루드 하게 되고 그러다보면 한번씩 'struct' type redefinition 이나 'class' type redefinition 어쩌구 하면서 에러가 발생할 때가 있다.
이런 경우 에러 내용 그대로 타입이 재정의 되었다는 얘기인데 이것은 일반적으로 아래 그림과 같은 경우에 발생한다.
사용자 삽입 이미지

그림에서 처럼 A.h 파일에 어떤 클래스나 타입을 정의해 놓았을 때 그 타입을 이용하기 위해 B.h 와 C.h에서 A.h를 인클루드하게 되고 D.c에서는 B.h와 C.h가 필요해서 둘을 인클루드하게 된다. 이런 경우 A.h 에서 정의한 타입을 D.c에서는 같은 내용을 두번 사용하게 되는 것이므로 이로 인해서 type redefinition이 발생하는 것이다.
C/C++프로그램을 어느정도 해봤다면 처음에는 누구나 type redefinition 이 발생 했을때 당혹스럽고 무엇 때문에 에러가 발생하는지 몰라서 헤매었던 기억이 한번씩은 있을것이다. type redefinition 같은 에러를 방지하기 위한 좋은 팁이 있는데 아래와 같이 A.h를 작성하는 것이다.
사용자 삽입 이미지
#ifndef 를 이용해서 A_H 라는 것이 디파인 되어 있는지 확인하고 디파인 되어 있지 않을 경우 아래에 A_H를 디파인한다. 그리고 필요한 코드를 작성하고 맨 마지막에 #endif를 이용해서 코드를 끝내는 것이다. 이렇게 해두면 위의 그림에서와 같이 B.h와 C.h를 같이 인클루드함으로써 발생하는 type redefinition을 원천적으로 방지하게 되는 것이다.

크리에이티브 커먼즈 라이선스
Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시 2.0 대한민국 라이선스에 따라 이용하실 수 있습니다.
TRACKBACK 0 AND COMMENT 2
예전에 Visual Studio 6.0 을 사용할때(요즘도 쓰긴하지만..) CString 을 string 으로 변환하기 위해서 항상 아래와 같이 사용했었다.

string s;
CString cs("TEST");

s = (LPCTSTR)cs;

하지만 요즘에 Visual Studio 2005 를 많이들 쓰는데 이런 경우 위와 같이 변환하면 제대로 안될 수 있다.
이런 경우 CT2CA 라는 클래스을 이용해서 변환하면 되는데 사용 방법은 아래와 같다.

string s;
CString cs("TEST");
CT2CA ctca(cs);

s = ctca;

난 요즘 Visual Studio 6.0 을 어쩔수 없이 자주 쓰는데 2005를 한번씩 쓸때마다 항상 느끼는게
6.0 보단 확실히 2005가 편한것 같다.
어서 빨리 6.0 안쓸려면 지금 하는 일을 끝내야 그만쓸텐데...끝이 보이지 않아..ㅠㅠ
크리에이티브 커먼즈 라이선스
Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시 2.0 대한민국 라이선스에 따라 이용하실 수 있습니다.
TRACKBACK 0 AND COMMENT 0

ARTICLE CATEGORY

분류 전체보기 (42)
개발 노트 (1)
초보의 알고리즘 (17)
프로그래밍 팁 (13)
기타 등등등등등 (11)

CALENDAR

«   2012/05   »
    1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31    

ARCHIVE

LINK