2009年03月12日

正規表現で数値を3桁毎のカンマ区切り形式に変換(C++編)

「C++ Boostのインストール(Windows編)」
http://programmer-toy-box.sblo.jp/article/14267315.html
もしくは、
「C++ Boostのインストール(Windows + VisualC++ 2008編)〜バイナリインストール」
http://programmer-toy-box.sblo.jp/article/27347453.html

でBoostがインストールされていることが前提です。

#include <iostream>
#include <string>
#include <boost/regex.hpp>
using namespace std;

int main() {
boost::regex r6("(\\d)(?=(\\d{3})+(?!\\d))");
string replace6("\\1,");
string str6 = "1234567890";
string res6 = boost::regex_replace(str6, r6, replace6);
cout << res6 << endl;
//"1,234,567,890"になります。
return 0;
}
posted by 台北猫々 at 19:58| Comment(0) | TrackBack(0) | 技術メモ(Windows C/C++)

2009年03月03日

「C++ Boostのインストール(Windows + VisualC++ 2008編)〜バイナリインストール」

以前に「C++ Boostのインストール(Windows + VisualC++ 2008編)」でBoostをソースインストールしましたが、
いつのまにかバイナリインストーラーが配布されていましたので、そのメモ。

前提条件:
・WindowsXP SP2
・VisualC++ 2008

1.インストーラー入手
Boost Consulting
http://www.boost-consulting.com/products/free
から、「BoostPro Binary Installer for Visual C++」をダウンロードします。
(本稿では、BoostPro 1.37.0 Installer (190K .exe)を使用します。)

※現在は、アカウントを登録しないとダウンロードできないようですね。

2.Boostをインストール
ダウンロードしたインストーラー(boost_1_37_setup.exe)を適当なフォルダにコピーして、
ダブルクリックして起動します。

以下のように対話方式でインストール操作を行います。

boostinstall2_01.jpg

boostinstall2_02.jpg

boostinstall2_03.jpg

boostinstall2_04.jpg

boostinstall2_05.jpg
「Boost Regex」->「VC9.0」を追加選択します(他にも試したいものがあれば適宜選択して下さい)。

boostinstall2_06.jpg
デフォルトの"C:\Program Files\boost\boost_1_37"にインストールします。

boostinstall2_07.jpg

3.VisualC++ 2008の設定

「ツール」→「オプション」→「プロジェクトおよびソリューション」→「VC++ディレクトリ」→ 「ディレクトリを表示するプロジェクト」→「インクルード ファイル」に"C:\Program Files\boost\boost_1_37"を加える。
boostinstall2_08.jpg

「ツール」→「オプション」→「プロジェクトおよびソリューション」→「VC++ディレクトリ」→ 「ディレクトリを表示するプロジェクト」→「ライブラリ ファイル」に"C:\Program Files\boost\boost_1_37\lib"を加える。
boostinstall2_09.jpg
完了です!

posted by 台北猫々 at 21:19| Comment(0) | TrackBack(0) | 技術メモ(Windows C/C++)

2008年05月27日

正規表現で、文字列は全て半角英数字か?のチェック(C++編)

「C++ Boostのインストール(Windows編)」
http://programmer-toy-box.sblo.jp/article/14267315.html
もしくは、
「C++ Boostのインストール(Windows + VisualC++ 2008編)」
http://programmer-toy-box.sblo.jp/article/14873765.html

でBoostがインストールされていることが前提です。

SJIS対応です。

#include <iostream>
#include <string>
#include <boost/regex.hpp>
using namespace std;

int main() {
boost::regex r5("^[0-9A-Za-z]+$");
boost::smatch m5;
string str5 = "abcdefghijklmnopqrstuvwxyz0123456789";

if( boost::regex_search(str5, m5, r5) ) {
cout << "すべて半角英数字である" << endl;
} else {
cout << "半角英数字でない文字がある" << endl;
}

return 0;
}

posted by 台北猫々 at 20:58| Comment(0) | TrackBack(0) | 技術メモ(Windows C/C++)

2008年05月23日

正規表現で、文字列は全て半角カタカナか?のチェック(C++編)

「C++ Boostのインストール(Windows編)」
http://programmer-toy-box.sblo.jp/article/14267315.html
もしくは、
「C++ Boostのインストール(Windows + VisualC++ 2008編)」
http://programmer-toy-box.sblo.jp/article/14873765.html

でBoostがインストールされていることが前提です。

SJIS対応です。

#include <iostream>
#include <string>
#include <boost/regex.hpp>
using namespace std;

int main() {
boost::regex r4("^(?:[\xA6-\xDF])+$");
boost::smatch m4;
string str4 = "ハンカクカタカナデアル";

if( boost::regex_search(str4, m4, r4) ) {
cout << "すべてが半角カタカナである" << endl;
} else {
cout << "半角カタカナではない文字がある" << endl;
}
return 0;
}

posted by 台北猫々 at 21:39| Comment(0) | TrackBack(0) | 技術メモ(Windows C/C++)

2008年05月15日

正規表現で、文字列は全て全角カタカナか?のチェック(C++編)

「C++ Boostのインストール(Windows編)」
http://programmer-toy-box.sblo.jp/article/14267315.html
もしくは、
「C++ Boostのインストール(Windows + VisualC++ 2008編)」
http://programmer-toy-box.sblo.jp/article/14873765.html

でBoostがインストールされていることが前提です。

SJIS対応です。

#include <iostream>
#include <string>
#include <boost/regex.hpp>
using namespace std;

int main() {

boost::regex r3("^(?:\x83[\x40-\x96])+$");
boost::smatch m3;
string str3 = "ゼンカクカタカナデアル";

if( boost::regex_search(str3, m3, r3) ) {
cout << "すべてが全角カタカナである" << endl;
} else {
cout << "全角カタカナではない文字がある" << endl;
}

return 0;
}

posted by 台北猫々 at 21:14| Comment(0) | TrackBack(0) | 技術メモ(Windows C/C++)

2008年05月13日

正規表現で、文字列は全て平仮名か?のチェック(C++編)

「C++ Boostのインストール(Windows編)」もしくは、
「C++ Boostのインストール(Windows + VisualC++ 2008編)」でBoostがインストールされていることが前提です。

SJIS対応です。

#include <iostream>
#include <string>
#include <boost/regex.hpp>
using namespace std;

int main() {
boost::regex r2("^(?:\x82[\x9F-\xF1])+$");
boost::smatch m2;
string str2 = "ひらがなである";
if( boost::regex_search(str2, m2, r2) ) {
cout << "すべてが平仮名である" << endl;
} else {
cout << "平仮名ではない文字がある" << endl;
}
return 0;
}
posted by 台北猫々 at 22:14| Comment(0) | TrackBack(0) | 技術メモ(Windows C/C++)

2008年05月12日

C++ Boostのインストール(Windows + VisualC++ 2008編)

コードなにがしにも投稿していますが、こちらにもメモ。

Boostのインストール方法のWindows + VisualC++2008の場合(ソースコンパイル版)です。

2008.05.10現在、VisualC++ 2008(9.0)用のBoostのGUIインストーラーは提供されていないので、ソースを入手して、コンパイル・インストールします。

2009.03.03 バイナリインストーラーが配布されていました。
「C++ Boostのインストール(Windows + VisualC++ 2008編)〜バイナリインストール」


【環境】
・WindowsXP SP2
・VisualC++ 2008 ExpressEdition

1.ソースの入手
Boost C++ Libraries
http://sourceforge.net/project/showfiles.php?group_id=7586
からboost_1_35_0.zip(2008.05.10現在の最新)をダウンロードします。

2.ビルドツールの入手
Boost C++ Libraries
http://sourceforge.net/project/showfiles.php?group_id=7586
からboost-jam-3.1.16-1-ntx86.zip(2008.05.10現在の最新)をダウンロードします。

3.作業フォルダへの解凍/展開
本稿では、C:\usr\local\boost_1_35_0を作業フォルダとします。1.と2.を解凍したものを、作業フォルダにコピーします。

BoostInstall_VC2008_00.jpg

結果として、作業フォルダは↑のようなファイル配置になっているはずです。

4.ソースのビルド(コンパイル)

DOSコマンドプロンプトを起動して、cdコマンドで作業フォルダに移動して、↓のコマンドを実行します。(画面の都合で折り返していますが、実際は1行です。)

bjam.exe --build-type=complete --toolset=msvc --prefix="C:\Program Files\Microsoft Visual Studio 9.0\VC" install

BoostInstall_VC2008_01.jpg

ビルドは相当時間がかかる(Intel Core2 Duoで数時間)ので、覚悟して下さい(笑

BoostInstall_VC2008_02.jpg

ビルド完了です。インクルードファイルは、C:\Program Files\Microsoft Visual Studio 9.0\VC\include\boost-1_35に展開され、ライブラリ・DLLファイルは、C:\Program Files\Microsoft Visual Studio 9.0\VC\libに展開されます。

5.VisualC++ 2008の設定

BoostInstall_VC2008_03.jpg

「ツール」→「オプション」→「プロジェクトおよびソリューション」→「VC++ディレクトリ」→ 「ディレクトリを表示するプロジェクト」→「インクルード ファイル」に C:\Program Files\Microsoft Visual Studio 9.0\VC\include\boost-1_35を加える。

完了です。
posted by 台北猫々 at 21:47| Comment(0) | TrackBack(0) | 技術メモ(Windows C/C++)

2008年05月02日

正規表現で、文字列は全てASCII文字か?のチェック(C++編)

「C++ Boostのインストール(Windows編)」
http://programmer-toy-box.sblo.jp/article/14267315.html
でBoostがインストールされていることが前提です。

SJIS対応です。


#include <iostream>
#include <string>
#include <boost/regex.hpp>
using namespace std;

int main() {

boost::regex r1("^[\x20-\x7E]+$");
boost::smatch m1;
string str1 = " abcdefghijklmnopqrstuvwxyz!#$&'()[]@";

if( boost::regex_search(str1, m1, r1) ) {
cout << "すべてがASCIIである" << endl;
} else {
cout << "ASCIIではない文字がある" << endl;
}
return 0;
}

posted by 台北猫々 at 08:00| Comment(0) | TrackBack(0) | 技術メモ(Windows C/C++)

2008年04月21日

C++ Boostのインストール(Windows編)

Boostの正規表現機能を使うために、Boost環境を構築しましたので、メモ。

前提条件:
・WindowsXP SP2
・VisualC++ 2005

1.インストーラー入手
Boost Consulting
http://www.boost-consulting.com/products/free
から、「BoostPro Binary Installer for Visual C++」をダウンロードします。
(本稿では、BoostPro 1.34.1 Installer (188K .exe)を使用します。)

2.Boostをインストール
ダウンロードしたインストーラー(boost_1_34_1_setup.exe)適当なフォルダにコピーして、
ダブルクリックして起動します。

以下のように対話方式でインストール操作を行います。
BoostInstall01.jpg

BoostInstall02.jpg

BoostInstall03.jpg

BoostInstall04.jpg

BoostInstall05.jpg
とりあえず全部入れちゃいます!

BoostInstall06.jpg
本稿では、"C:\usr\local\boost\boost_1_34_1"にインストールします。

BoostInstall07.jpg

BoostInstall08.jpg
「はい」をクリックして、PATHの設定を行います。

BoostInstall09.jpg

3.VisualC++ 2005の設定

「ツール」→「オプション」→「プロジェクトおよびソリューション」→「VC++ディレクトリ」→ 「ディレクトリを表示するプロジェクト」→「インクルード ファイル」に C:\usr\local\boost\boost_1_34_1 を加える。

BoostInstall10.jpg

「ツール」→「オプション」→「プロジェクトおよびソリューション」→「VC++ディレクトリ」→ 「ディレクトリを表示するプロジェクト」→「ライブラリ ファイル」に C:\usr\local\boost\boost_1_34_1\lib を加える。

BoostInstall11.jpg

完了です!
posted by 台北猫々 at 18:48| Comment(0) | TrackBack(0) | 技術メモ(Windows C/C++)

2008年02月17日

文字コード変換ライブラリ「ICU」での文字コード変換処理

UTF-8エンコーディングの文字が書かれているファイル("utf8_src.txt")を準備して、プログラムでファイルの1行目を読み込み、その文字列からUnicodeStringオブジェクトを構築してから、SJISにコード変換するサンプルです。

文字コード変換ライブラリ「ICU」セットアップ
が行われいることが前提です。


#define WIN32_LEAN_AND_MEAN
#include <stdio.h>
#include <string>
#include <fstream>


#include <unicode/unistr.h> // ICU


int main(int argc, char* argv[])
{
std::fstream r("utf8_src.txt");
std::string str;
r >> str;


//一旦Unicodeで文字列オブジェクトを構築して、extractメソッドで
//他のマルチバイト文字に変換します。


//Unicodeオブジェクト構築 例:"shift_jis"、 "utf8"、 "euc-jp"
icu::UnicodeString src(str.c_str(), "utf8");


//変換後の文字列長を取得
int32_t len = src.extract(0, src.length(), NULL, "shift_jis");


//変換後文字列の格納領域を準備
char* result = new char[len + 1];


//文字コード変換
src.extract(0, src.length(), result, "shift_jis");


//変換結果確認
printf("[%s]\n", result);


delete [] result;
return 0;
}


posted by 台北猫々 at 11:59| Comment(0) | TrackBack(0) | 技術メモ(Windows C/C++)

文字コード変換ライブラリ「ICU」セットアップ

VisualC++ 2005 ExpressEdition向けのセットアップ方法です。

1.IBM ICUのホームページ
http://www.icu-project.org/
↑のDownload ICUから辿っていき、「icu4c-3_8_1-Win32-msvc8.zip」をダウンロード
します。

2.「icu4c-3_8_1-Win32-msvc8.zip」を適当な場所に解凍します。ここでは、
"c:\\usr\local"に解凍することにします。

3.VC++のディレクトリ設定
[ツール]>[オプション]でオプションダイアログを起動し、
[プロジェクトおよびソリューション]>[VC++ディレクトリ]で、ICUのディレクトリを
設定します。

[インクルードファイル] → c:\\usr\local\include
[ライブラリファイル] → c:\\usr\local\lib

※この後は、UnicodeStringを使用してUTF8←→SJIS/EUC変換するだけのICU機能を使うための最低限の設定になります。

4.プロジェクトの設定
[プロジェクト]>[プロパティ]でプロパティダイアログを起動し、
[構成プロパティ]>[リンカ]>[入力]で、[追加の依存ファイル]に"icuuc.lib"を追記します。
#こんな感じになります。→ kernel32.lib $(NoInherit) icuuc.lib
#今回は文字コードの変換処理のみ使用するので"icuuc.lib"だけです。

5.DLLの配置
ソリューションで、exeファイルが生成されるディレクトリ(※1)に"icudt38.dll"と
"icuuc38.dll"をコピーします。
#今回は文字コードの変換処理のみ使用するので2つだけです。

(※1)例では〜\Visual Studio 2005\Projects\<ソリューションフォルダ>\debug もしくは、\releaseです。
posted by 台北猫々 at 10:23| Comment(0) | TrackBack(0) | 技術メモ(Windows C/C++)

2008年01月16日

スレッドプログラム訂正

昨日書いたスレッドプログラムで誤りがありました。

_beginthreadexでは、スレッドの切り離しはできないと書いたのですが、できます。親スレッドで、子スレッドのハンドルをCloseHandleしても、子スレッドの動作には影響ないようです。

不勉強でした。猫


良かったらクリックお願いします→banner_01.gif
posted by 台北猫々 at 18:56| Comment(0) | TrackBack(0) | 技術メモ(Windows C/C++)

2008年01月15日

スレッドプログラム

_beginthread (Cランタイム:CRT)
_beginthreadex (Cランタイム:CRT)
CreateThread (WindowsAPI)

MFCを使わない場合、以上の3種類の選択肢があるわけですが、MSDNでCreateThread の説明を見ると、
===================================================
C のランタイムライブラリに記録されている関数を使うスレッドは、CreateThread 関数と ExitThread 関数ではなく、C のランタイム関数である beginthread 関数と endthread 関数を使うべきです。この方法に従わないと、ExitThread 関数を呼び出したときにわずかなメモリリークが発生します。
http://msdn.microsoft.com/library/ja/default.asp?url=/library/ja/jpdllpro/html/_win32_createthread.asp
===================================================
とか書かれているので、つまり、C標準関数を使用するスレッドでは使えませんということですよね?相当、使用する場面が限られるような。。。

で、_beginthreadを見ると、
===================================================
_beginthread よりも _beginthreadex を使用した方が安全です。_beginthread によって生成されたスレッドの終了が早すぎると、_beginthread の呼び出し元に返されるハンドルが無効になる可能性や、別のスレッドを指す可能性があります。
http://msdn2.microsoft.com/ja-jp/library/kdzttdcb(VS.80).aspx
====================================================
と書かれているので、つまりは_beginthreadexを使いなさいということになるのかなと。

で、_beginthreadexですが、これの特徴は、スレッド内で_endthreadexを呼んで終了した後に、親スレッドでスレッドハンドルをCloseHandleをしないとメモリリークするので、スレッドを切り離せません。これってたまに不便な気がします。
→すいません。。。早とちりです。スレッド終了(_endthreadex)前にを呼ぶ前にCloseHandleしても、スレッド処理は続行されるようです。結果として、切り離すことはできますね。猫

なんか種類はあるんですけどね。ややこしくしているだけのような気もします。

良かったらクリックお願いします→banner_01.gif







posted by 台北猫々 at 22:54| Comment(0) | TrackBack(1) | 技術メモ(Windows C/C++)

2008年01月12日

ソケットの高水準入出力

昨日公開しましたSocketStreamクラスですが、機能としてはソケットの対して、fgetsやfputsのような高水準仕様での入出力を可能にします。

Linuxだとソケット記述子をfdopenするだけなのですが、Windowsの場合は、工夫が必要で、

ソケットを作成する前に、
int sockopt = SO_SYNCHRONOUS_NONALERT;
setsockopt(INVALID_SOCKET, SOL_SOCKET, SO_OPENTYPE, (char *)&sockopt, sizeof(sockopt));
を行って、

さらに作成したソケットハンドルについて
int sock_osfhandle = _open_osfhandle(socket, _O_RDONLY);
を行ってファイルハンドルに変換してからfdopenしなければなりません。

この辺は、Rubyのソースなどを参考にして組んでみましたが、setsockopt関数の"OPENTYPE"や"SO_SYNCHRONOUS_NONALERT"は、MSDNを見ると非推奨のようなことが書いてあるのですよね。。。まあ、モウマンタイでしょう。
posted by 台北猫々 at 21:14| Comment(0) | TrackBack(0) | 技術メモ(Windows C/C++)

2008年01月06日

ソケット処理〜ホスト情報の取得


#include <winsock2.h>

/**
* 名前もしくはIPアドレスからホスト情報を獲得する.
* @param const char* lpszHostName : ホスト名 or IP.
* @return 成功:ホスト情報構造体のアドレス 失敗:NULL.
*/
struct hostent* getHostByName(const char* lpszHostName)
{
struct hostent* lpWorkHost=NULL;

::in_addr in;
in.s_addr = ::inet_addr(lpszHostName);
if (in.s_addr == INADDR_NONE) {
lpWorkHost = ::gethostbyname(lpszHostName);
} else {
lpWorkHost = ::gethostbyaddr(reinterpret_cast<char *>(&in), sizeof(in), AF_INET);
}
return lpWorkHost;
}

返却領域がstaticのためマルチスレッドセーフではありません。


↓で構築したVisualC++ 2005 Express Editionでコンパイルしました(ただし、Ws2_32.libを追加しています)。
http://winter-tail.sakura.ne.jp/nmap/setup.html

良かったらクリックお願いします→banner_01.gif
posted by 台北猫々 at 21:31| Comment(0) | TrackBack(0) | 技術メモ(Windows C/C++)

2007年12月27日

Windows版のgettimeofday関数です。

一応ミリ秒がとれます。まあ、タイマ分解能はOSに依存しちゃいますがね。

#include <windows.h>
#include <time.h>

struct timezone {
int tz_minuteswest;
int tz_dsttime;
};

#define EPOCHFILETIME (116444736000000000i64)

int gettimeofday(struct timeval *tv, struct timezone *tz)
{
FILETIME tagFileTime;
LARGE_INTEGER largeInt;
__int64 val64;
static int tzflag;

if (tv)
{
GetSystemTimeAsFileTime(&tagFileTime);

largeInt.LowPart = tagFileTime.dwLowDateTime;
largeInt.HighPart = tagFileTime.dwHighDateTime;
val64 = largeInt.QuadPart;
val64 = val64 - EPOCHFILETIME;
val64 = val64 / 10;
tv->tv_sec = (long)(val64 / 1000000);
tv->tv_usec = (long)(val64 % 1000000);
}

if (tz)
{
if (!tzflag)
{
_tzset();
tzflag++;
}

//Visual C++ 6.0でOKだった・・
//tz->tz_minuteswest = _timezone / 60;
//tz->tz_dsttime = _daylight;

long _Timezone = 0;
_get_timezone(&_Timezone);
tz->tz_minuteswest = _Timezone / 60;

int _Daylight = 0;
_get_daylight(&_Daylight);
tz->tz_dsttime = _Daylight;
}

return 0;
}



↓で構築したVisualC++ 2005 Express Editionで動作確認しました。
http://winter-tail.sakura.ne.jp/nmap/setup.html

良かったらクリックお願いします→banner_01.gif
posted by 台北猫々 at 21:07| Comment(0) | TrackBack(1) | 技術メモ(Windows C/C++)