日記緑ログ

2005/05/01 ~ 2005/05/30

目次

戻る

Blog

マルチバイト文字列とワイド文字列の相互変換

[Create: 2005/05/01 20:49] [LastUpdate: 2005/05/01 21:07]

ANSI Cにはマルチバイト文字列とワイド文字列の相互変換用の関数が存在しています。

mbstowcsやwcstombs

あるいは

mbsrtowcsやwcsrtombs

を使えばお手軽に文字列の相互変換が可能です。

("r"がついている関数はよりきめ細かな処理が可能です。)

(一文字のみの変換にはmbtowcとwctomb、mbrtowcとwcrtombを使えばよいでしょう。)

特に注意するところはありませんので適当に使用しましょう。ここではC++のstd::stringとstd::wstringを相互に変換する関数を作っておいておきます。

std::wstring multibytestring_to_widestring(std::string mbs){

size_t count = std::mbstowcs(NULL, mbs.c_str(), 0);

if(count == (size_t)-1){

throw std::runtime_error(""); // 適当な例外を投げているだけです。

}

wchar_t* tmp = new wchar_t[count + 1];

std::mbstowcs(tmp, mbs.c_str(), count + 1);

std::wstring ret = tmp;

delete[] tmp;

return ret;

}

std::string widestring_to_multibytestring(std::wstring ws){

size_t count = std::wcstombs(NULL, ws.c_str(), 0);

if(count == (size_t)-1){

throw std::runtime_error(""); // 適当な例外を投げているだけです。

}

char* tmp = new char[count + 1];

std::wcstombs(tmp, ws.c_str(), count + 1);

std::string ret = tmp;

delete[] tmp;

return ret;

}

throwしている例外は適当です。またnewで例外を投げない処理系は考えていません。適任NULLチェック等を行ってください。さらに言えばメモリの無駄遣いが過ぎるかもしれませんがご勘弁を。

これだけです。まあどこにでもある話ですが。

アルコールの利用方法

[Create: 2005/05/03 20:24] [LastUpdate: 2005/05/03 20:28]

余ったワインは工業用に使用せよ

以下引用----

  生産過剰になっているフランスやスペイン産のワイン約55万キロリットルを工業用アルコールや燃料として転用するために計1億4500万ユーロ(約200 億円)の補助金が欧州連合(EU)から両国に支払われる。EU欧州委員会が29日発表した。欧州域外からのワイン輸入が増えていることに対応した措置だ。

 欧州委報道官は「ワイン消費が全体的に減り、オーストラリアや南アフリカ、南米産ワインの輸入も急増している」と語り、フランスやスペインでワイン価格が下がり、在庫が増えていることを明らかにした。

  フランス産の中級ワイン15万キロリットル、スペイン産のテーブルワイン40万キロリットルが対象になる。補助金の割り当ては、相対的に高級ワインが多い 仏産に手厚くするため、おおむね仏に4割、スペインに6割になる。蒸留してできたアルコールは工業用にだけ使い、人の口に入ることはないという。

----引用終了

つまりアルコールを燃料やらなんやらにするって言うことですね。

燃料にすることを考えると電気自動車よりもアルコール自動車のほうが使い勝手はよさそうな気がします。

微生物(細菌)の働きで燃料がバンバンできるわけですからメタンガスやエチルアルコールなどを利用する機器がわんさかでるようになったら面白くなりそうな気がします。エタノールは酒税がかかるかもしれないのですが…

INIファイル

[Create: 2005/05/12 21:29] [LastUpdate: 2005/05/13 06:12]

INIファイル(initialize file)は前時代の遺産ともいえるようなものですが、現在でもよく使われています。

なぜかといえばWindowsのレジストリはコンパクションが効かない(あるいは面倒)でサイズが肥大化する一方だからできるだけ影響をなくそうという考えでしょう。

ただWIN.INIやSYSTEM.INIを使うのはさすがにばかげていますのでお勧めしません。使うのは自分の製作したソフトウェアの設定を保存するときでしょう。

APIを使ってもいいのですがサイズに制限がありますし(16ビット時代の64kByteという制限があるところにはある)、Windowsのバージョンによって挙動も異なってくるようですので場合によっては独自のライブラリを使ってもいいと思います。

DelphiやBCBあたりならVCLにTMemIniFileがありますのでそれを使えばいいと思います。というか使ったほうがいいと思います。というよりも使うべきです。

Cでは何を使えばいいかというと、自作してもそれほど面倒ではないと思いますが同じことを考えている人は数多くいるのでそういう人に助けてもらってもいいと思います。

お勧めをあげておきます。

iniParser: stand-alone ini Parser library in ANSI C はWindows APIにそれとなく似ていてしかもANSI Cの範囲内でかかれているので可搬性も抜群な代物です。ライセンスもうるさくないので問題なければ使ってみるといいかもしれません。

あと日本語でプログラマ's 研究所のソースライブラリに拡張iniファイルの開発がありますのでそれもお勧めしておきます。

その他にC++やらJavaやらPerlなど様々な言語に様々な人が様々な手法で様々に公開しています。様々。様々なことに.NETでも作っている人がいます。なんと様々なことか。Code Projectにはそれこそ様々な人が様々な知恵を出し合って様々なサンプルやライブラリが公開されています。ここにも様々なIniFile用のライブラリ等が公開されていますので一度見てみるといいかもしれません。

.NET環境だと構成ファイル(.configという拡張子のXML)を使うのがいいのかもしれません。INI ファイルと構成ファイルの読み書き(VB.NETドキュメント)には『アプリケーションの情報データを保存する場合は、通常 INI ファイル、構成ファイルまたは、レジストリを使用することで実現します。』と、載っています。構成ファイルについては構成ファイルを参照するといいかもしれません。

最 後に注意なんですが、このINIファイルを実行ファイルと同じディレクトリに保存してもいいんですがマルチユーザー環境だといささか困った状態になること も考えられます(私はPCは一個人で使いたいんですけど相変わらず高価で難しいですよねぇ)。その場合には設定を個人ごとに保存しないとまずいでしょう。 Windows 2000 アプリケーション仕様書(デスクトップ) の4 章 データおよび設定の管理にはSHFOLDER.DLLからエクスポートされるSHGetFolderPathにCSIDL_APPDATAを渡してその下に

1.会社名

2.製品名

3.バージョン

とディレクトリ階層を構築し、その下の任意のファイルまたはディレクトリに設定を保存するように推奨するように書かれています。

GetEnvironmentVariableでAPPDATAをとっても同じようにパスが取得できそうですが、これだと環境変数に依存するのでまずいのでしょう。MSの言う通りにしていたほうが安心かと思います。

ゲームのメインループ

[Create: 2005/05/15 21:46] [LastUpdate: 2005/05/15 22:04]

普通Windowsのプログラムはメッセージループがあって、イベントが発生するとウィンドウプロシージャが呼ばれ、そこから処理が分岐します。

一方ゲームではリアルタイムに処理をしなければならないためイベントをまってはいられません。

どうするかというと大体

while(1){

 if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)){

 if(msg.message == WM_QUIT)

 break;

 TranslateMessage(&msg);

 DispatchMessage(&msg);

 }

 else{

 Sleep(1);

 MainLoop();

 }

}

というような処理になると思います。

しかしこういう『お行儀のよい』方法を使うとMainLoopの処理が煩雑になり面倒です。

そこで邪道ではありますが

WinMainのラストで

return MainLoop();

とでもしておき

int MainLoop(){

 処理1

 処理2

 ・・・

 Wait+MessageLoop

}

とするとメインループが非常に簡潔に書け、DOSなどの時代で行っていたように自分勝手に処理をかけて非常に小気味いい気がします。

さてこのMessageLoopですがVBのDoEventsやVCLのApplication.ProcessMessagesと同じような処理をすれば言いのですね。

つまり

int DoEvents(){

 if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)){

 if(msg.message == WM_QUIT)

 return -1; // 今すぐアプリケーションを終了せよ

 TranslateMessage(&msg);

 DispatchMessage(&msg);

 }

 return 0;

}

まあこういった処理になるんじゃないでしょうか。

キー入力などはメッセージを処理してもいいし、DirectInputでもいいし、この際GetAsyncKeyStateなどを使ってもいいでしょう。

邪悪テクニックですが案外有効ですよ。

HINSTANCEが知りたい

[Create: 2005/05/17 21:44] [LastUpdate: 2005/05/17 21:56]

Windowアプリケーションを起動するとインスタンスハンドル(HINSTANCE)がわたってきます。

これを使ってWindowを開いたりするわけですがその辺の関数でこれを使いたいときがあります。

グローバル変数に保存しておいてもいいのですが芸が無いのでウィンドウハンドル(HWND)から取得するのがいいでしょう(ウィンドウハンドルはウィンドウプロシージャーに渡ってくる)。

そのとき使うAPIがGetWindowLongですが実はこれは古いのでGetWindowLongPtrを使いましょう。使い方はいっしょです。

GetWindowLongPtrのほうが移植性が高いのでこっちを使いましょう。

同じようなAPIにGetClassLongとGetClassLongPtrもあります。他にもあるかも。こちらもPtr付きのほうを積極的に使うべきです(GetClassWordなどもあったりするが関係ない)。

時計

[Create: 2005/05/19 21:22] [LastUpdate: 2005/05/19 21:30]

137億年で誤差0.4秒 超高精度時計へ一歩

朝日新聞にリンクしたほうが良いのだろうか…

それはさておき、この137億年というのは今私たちのいる宇宙が誕生してから今まで過ぎた年月の推定値ということになっています。

大体300億年で宇宙は冷えて駄目になるとか、縮んで消滅するとか言われているわけで最初から最後まで計っても一秒狂うか狂わないかぐらいの誤差しかないわけです。

地 球の回転は実は速くなったり遅くなったり揺らいでいますが、最近はずっと遅くなる傾向にあるようです。そのため閏秒も大量にさしはさまれているわけですが こういう高精度の時計が増えてくるとこの時間というものの絶対性が重要になってくると思うのですがそれは別に問題ではなくて、要するに何がやばいって自然 との調和を取るのが面倒になってくるとか、千年後に人類が火星に移住したら時間は地球と同期するのかとか、もっと遠くまでいけるようになったらどうなんだ とかそっち系の疑問もないわけではありません。

意味がわからないけどこのへんで。

UNICODE in Windows

[Create: 2005/05/22 20:35] [LastUpdate: 2005/05/22 20:57]

最近ネコも杓子もUNICODEでこりゃあいい傾向だなぁ。

UNICODE は創めの無茶な思想で怪しげな部分があったりするわけで特に漢字圏の我々にとっては困ったちゃんな部分も無いわけではないのですが全世界的な文字を十分に 使えるレベルで提供されているわけでそこそこ便利です。最近は複雑化してきていますし、たまにハングル文字の大移動とか、コード振りのミスとかやらかした 感じがあるのも否めませんがWindowsNT系では内部UNICODEで助けられている部分がかなりあるはずです。

海外ソフトでの文字コードのトラブルも減ってきたと思います。

このそこそこ便利なUNICODE、Windows95の時代でもサポートされています。もちろん古い規格なので最新版並みの対応とはいかないのですがある程度の使用には問題が無いはずです。

まあ対応といってもファイル名に使えるわけでもなく、単に内部で持つ文字に使えるということですが。

MultiByteToWideCharとWideCharToMultiByteを使えばShift_JISなどとUNICODEの相互変換が可能です。

内 部UNICODEにしておくと利点というか、Shift_JISなどを使うときには1バイト目と2バイト目を意識しながら文字列処理をしないといけないと ころをあまりカリカリしながら処理しなくてもいいという建前があります(実際は厳密にはUNICODEでもそういう処理はしないと駄目な部分がある)。

そ れが建前だとすると利点なんて無いじゃないかと思うのは早計で、日本語でも中国語でも、アラビアンでもハングルでも、ロシア語でも同じ処理でとおるわけ で、今までコードページごとに処理を切り替えないとおかしいことになっていたのが解消されるわけでやっぱり利点はあるのです。

というお話はさておいて、Win9xでも例えばエディタを作るとして、内部UNICODEで文字列処理をしたとして、さあ、表示はどうしよう?DrawText APIならお手軽処理できますが、お勧めはやっぱりTextOut。

TextOutの何がいいかというと

解説

この関数は、例外的に Windows 95/98 でも Unicode 版と ANSI 版がサポートされています。

ここです。つまりこれがいいたかっただけです。

9xだと現在のコードページ以外の文字は化ける可能性が高いのですが(フォントも入ってない可能性が高い)TextOutWを使うとWideCharToMultiByteの手間も要らないし、うまくすればちょっとステキに表示を出せるかもしれない。なんて素敵なAPI。

チャボの雛

[Create: 2005/05/23 19:00] [LastUpdate: 2005/05/23 19:02]

チャボのひよこ

チャボの雛が孵りました。

写真をなかなか撮らせてくれません。

バイオ燃料

[Create: 2005/05/28 07:28] [LastUpdate: 2005/05/28 07:34]

三井物産、バイオ燃料事業に参加

重要なのは三井物産ではないので一部抜粋

 『ブラジル産のバイオエタノールはサトウキビを原料にしたバイオマス(生物資源)燃料で、地球温暖化ガスの削減に役立つ。水素と酸素を反応させて電気を取り出す燃料電池とともに注目を集めており、日本でもガソリンに混ぜて使うことが検討されている。』

つまりそういうことなんですが、ワインを燃料にするという話もありましたし、どうにも簡単に手に入る液体燃料というのはエタノールになりそうです。気体はというとおそらく牛糞や生ごみなどから容易に抽出可能なメタンなどになるんではないでしょうか。

石油というのは優れた効率の燃料ですがさっさとアルコール燃料にでもシフトして、電気は風力やら太陽光やらにすばやくシフトすればなんとは無しに石油の黒いイメージから透明なイメージの世界になりそうな気がします。なんとなくですが。

「繰り上がり分離法」とかなんとか

[Create: 2005/05/30 09:19] [LastUpdate: 2005/05/30 10:11]

『とおりすがりの業界人』さんによる高速掛け算メソッド「繰り上がり分離法」がどうもはやっていたりしたようです。

まあ行き着いたのはgooのトップで検索で知るコトバに高速掛け算メソッドとかいてあったので、「ほほう。乗算を高速化するテクニックか。これは多倍長整数~」と思ってみただけなんですが。メソッドなんて仰々しい名称をつかうとは広告業界の手法?

ど ういう方法かといえば掛け算を一桁ずつやるときに足さないで掛けっぱなしで行きましょう。とかなんとかいう話です。リンクを見たほうが早いのでそっちへ。 なるほど。小学校では普通掛け算の結果が二桁になったときは上の桁の右上に小さくメモ書きをして次の桁にいけというように教えます。

そして次の桁を計算したときに前の結果の二桁目と足し合わせることをします。

慣れるとメモを残さずにしかも高速に、まるで流れるように処理可能になるので実際は高速です。

そ れで、繰り上がり分離法だと足し算はあとですべてまとめてということで乗算の計算中の加算処理を分離して高速化してみるかという話になっています。どうに も九九を流すリズムに加算のリズムを組み込めないよーということらしいので、アブノーマルかどうかは知らないけれど、計算中はにくにじゅういちと口ずさめ るか、あるいはにくじゅうはちといいつつ二十一とかけるとか、そういうエスパーギャルはこなくていいよ。とそういう怪しげな話です。

絵をかくのが面倒なので適当

1.事始。掛け算と足し算を分離している思考

■が掛け算☆が足し算

─■──☆───

 └──┘

とループバックしたりする。

2.掛け算と足し算がスムースに同時進行できる思考

───■☆────

3.掛け算中に足し算も同時進行できるエスパー

───■──────

4.繰り上がり分離法

───■──────

しかる後

───☆──────

まあ分かってもらえると幸い。つまり1の人は計算が苦手だったりするのです。

場合によって

─■───☆───

 └☆─■┘

─■───☆───

 └☆─☆┘

などのバリエーションも考えられます。

そろばん屋さんはきっと2か3に落ち着くでしょう。

という前振りはさておいて、暗算をするとき足し算引き算掛け算割り算はどれがどういう順番で計算をしますか?

小学校の筆算では足し算、引き算、掛け算は下の桁から、割り算は上の桁から(とはいっても内部で乗算するので上からとはいっても下から上がってきたりとても複雑)で教えていたりします。

かく言う私も小学二年ぐらいの筆算の足し算でそれはもう前にでて、黒板に書けというときに、

□45

+76

───

□□□

とかいうやつがあったら

□45

+76

───

1□□

□45

+76

───

12□

□45

+76

───

121

と喜び勇んで上から書いたら叱られました。

これは

□1

□45

+76

───

□□1

11

□45

+76

───

□21

11

□45

+76

───

121

とかかないと駄目だなどといわれたわけです。

これが計算速度を落とす罠で、こういうやり方をすると桁を行ったり来たりして遅いのです。

111222233となるように思えますが実際は二桁になるときに下の桁から言う人間は限られると思うので

1121(2)22232(3)33

となります()の中にかいてあるのはじゅういちだな。下桁は1だな。とかいてから上は、よしよし1だなと書いたときの話で流石にここまで冗長な処理をする人は居ないかと思いますが、これも基本として教わることだと思います。

()をつけずにかけば

11212223233

となり

111222233

と比べ長いのは明白ですが、ここでもまた罠があって、大抵は桁を移動すると0.5~2ぐらい処理時間をロスするのです。つまり倍近く遅い場合が出てきてしまいます。

で、どうすればいいのよ?と思うかもしれませんがこれは上の桁から処理するのが正解です。

11

 11

となり

121と計算してしまうわけですが、この処理の流れだと

223211212となり、移動分を含めても下から計算するより短くなっているような気がします。多分。