Windowsアプリケーションをコマンドプロンプトから実行した場合,実行終了を待たずに
プロンプトが戻ってきます。バッチファイルなどで順次処理をさせたい場合は,以下のように
STARTコマンドで終了を待つと良いでしょう。
START /WAIT アプリケーション名
詳細はコマンドプロンプトから START /? でヘルプを見てください。
longやshort型などの複数バイトデータをメモリ上に格納するとき,どのような順番でバイト
を並べていくかというのがエンディアンです。データの上位バイトを下位アドレス
(0番地に近い方)から並べるのがビッグエンディアン(Big Endian)で,上位アドレスから
並べるのがリトルエンディアン(Little Endian)と呼ばれています。
unsigned short us = 0xAABB; のメモリ上の配置
【ビッグエンディアン】 【リトルエンディアン】
アドレス: データ アドレス: データ
+0: AA +0: BB
+1: BB +1: AA
unsigned long ul = 0xAABBCCDD; のメモリ上の配置
【ビッグエンディアン】 【リトルエンディアン】
アドレス: データ アドレス: データ
+0: AA +0: DD
+1: BB +1: CC
+2: CC +2: BB
+3: DD +3: AA
なぜこのような種類があるかの詳細な説明は他に譲るとして,簡単に言えばプロセッサの生い立ちに
原因があるということです。モトローラ系のプロセッサはビッグエンディアン,インテル系のプロセッサは
リトルエンディアンです。まあ電源周波数が関東で50Hz,関西で60Hzなのと似たような状況です。
エンディアンの異なるコンピュータ同士でバイナリデータをやりとりするとデータの値がひっくり
返って問題が発生してしまうので,どちらのエンディアンを使用するかが大抵決められています。
ネットワークのTCP/IPではビッグエンディアンを使用することが決められていて,これをネット
ワークバイトオーダーと呼んだりします。
エンディアンの入れ替えは下記のようにマクロを使って行えます。
#define WORDSWAP( w ) ( LOBYTE( w ) << 8 | HIBYTE( w ) )
#define DWORDSWAP( dw ) ( LOBYTE( LOWORD( dw ) ) << 24 | HIBYTE( LOWORD( dw ) ) << 16 | LOBYTE( HIWORD( dw ) ) << 8 | HIBYTE( HIWORD( dw ) ) )
unsigned short us;
unsigned long ul;
us = 0xAABB;
us = WORDSWAP( us );
ul = 0xAABBCCDD;
ul = DWORDSWAP( ul );
また複数バイトのバイトオーダーを入れ替えるswab( )という関数があります。
さらにネットワーク関連のライブラリにhtonl( ), htons( ), ntohl( ), ntohs( )という
バイトオーダーの入れ替え関数が用意されています。このライブラリ関数はソースコード中に
以下の記述をすることによって使用できるようになりますが,上記のマクロで十分でしょう。
#include
#pragma comment( linker, "/DEFAULTLIB:wsock32.lib" )
文字列の中の単語を分離するには sscanf( ) などを使用すると思いますが,単語間のセパレータ文字が
いくつか種類がある時はなかなか難しいです。
そのような場合,トークン抽出関数 strtok( ) を利用すると便利です。
セパレータを複数(もちろん一種類でも可)指定して,トークン(単語)ずつ分離できます。
こんな便利な関数があるなんて最近まで知りませんでした。
詳細はヘルプを見てください。サンプルコードも載っています。
日本語を表すいわゆる全角文字のコードは、電子メールなどで使用されるJISコード、
WindowsやMacで使われるシフトJISコード、UNIXで用いられるEUCコードなどがあります。
詳しい話は他に譲るとして、ここではそれぞれのコード間でコードを変換するサンプルを掲載します。
これです。話が早いでしょ?(笑)
Windowsではフォルダやファイル名にもシフトJISコードが使用されていますが,困ったことに
フォルダの区切り文字である'\'(0x5c)が文字コードの2バイト目に存在する場合があるのです。
具体的には以下の文字の2バイト目が'\'(0x5c)です。
―ソЫ\噂浬欺圭構蚕十申曾箪貼能表暴予禄兔喀媾彌拿杤歃濬畚秉綵臀藹觸軆鐔饅鷭
フォルダ名の解析を行う場合などはこの点を考慮してプログラミングしなければなりません。
つまり「ソフト」とか「性能」とか「予定表」という名前のフォルダが存在しても期待通り
動作しなければなりません。文字を調査するには_ismbb 系ルーチンが有効でしょう。
詳細はヘルプを見てください。
【Unicode】
最近は全世界の言語を2バイト長の文字コードに集約しようとするUnicodeというものを
よく聞くようになりました。日本語や中国語の似たような形の文字は一つの文字に割り当ててしまう
というちょっと強引なコード体系でしたが,結局2バイトでは足りなくなり可変長のマルチバイト
文字コードになってきています。
一口にUnicodeといっても実はいろんなフォーマットがあります。
UTF-7, UTF-8, UTF-16BE, UTF-16LEというように全然集約されていません。
まったく勘弁して欲しいです…。
(UTF: Universal multi-octet character set Transformation Format)
UTF-7: いわゆるASCIIコードは1バイト,その他はBase64という符号化方法でコード化した文字コード(現在非推奨)。
UTF-8: ASCIIは1バイト,その他は2バイトから6バイトで符号化する文字コード。日本語は3バイトでコード化されるため効率が悪い。
UTF-16: ASCIIや日本語など(0x0000〜0xD7FF, 0xE000〜0xFFFF)は2バイト,それ以降は4バイトで表す。
符号化されたデータはリトルエンディアンとビッグエンディアンの2種類存在する。どちらで符号化されたかは
文書の先頭に「バイトオーダーマーク(0xFEFF)」を配置して区別することになる。
【マルチバイト文字】
文字を可変長バイトで表現する文字コードのこと。
ASCIIは1バイト,日本語は2バイトで表現するSJISや,Unicodeなどはマルチバイト文字である。
【ワイド文字】
主に2バイト固定長で表現される文字コードのこと。特に決まった文字コードがあるわけではないが
WindowsではUTF-16BEのようだ。
マルチバイト文字列(SJIS)とワイド文字列(UNICODE)の変換は以下のようにすることが可能です(VC++.NET2003で確認)。
ただし,最新のコンパイラでないと対応してないかもしれません。筆者愛用のVC++4.0はもちろん非対応でしたー!
char MultiByteString[16];
wchar_t WideString[8];
// ロケール設定
setlocale( LC_ALL, "Japanese" );
// マルチバイト文字列(SJIS)からワイド文字列(UNICODE)への変換
mbstowcs( WideString, "テスト", 16 );
// ワイド文字列(UNICODE)からマルチバイト文字列(SJIS)への変換
wcstombs( MultiByteString, WideString, 16 );
©Yutaka Wada(ana53), AirparkLab ALL RIGHTS RESERVED.