最近データーファイルの形式に悩んでいる。 例えば、RPGの敵データー、例えば、シューティングゲームのステージデーター あるいは家計簿データー、はたまた日記のデーター。 色々データーはあるのは良いのだが、それぞれ別のフォーマットだと、 読み込み/書き込みルーチンを書かなくてはならない。 これがまた結構面倒なので、たった一つのフォーマットで全部書きたい。 とすると、既にどこのだれかが万能フォーマットを用意してくれていそうだ。 と考えてみると、あった。あれだ。XMLだ。 というわけで今現在はXMLにはまり中。VBScriptやJavaScriptでも扱えるところが良い。 開発ツールが無くても全部メモ帳で事足りる。 もちろんXMLはVC++でもVB++でも扱える。Javaでも扱えるらしい。 さらに深みにはまっていったらVC++でXMLとかいう記事が出てくるかもしれない。
CStringは、
CString str = "Hoge"; LPTSTR data = (LPTSTR)(LPCTSTR)str; // ●dataを通してstrを書きかえられる。● data[0] = 'N'; |
例えば、次のプログラムを実行してみよう。
CString str1 = _T("Hoge"); CString str2 = str1; LPTSTR data1 = (LPTSTR)(LPCTSTR)str1; data1[0] = _T('T'); ::MessageBox(NULL, str1, _T("str1"), MB_OK); ::MessageBox(NULL, str2, _T("str2"), MB_OK); |
できる限りと言ったが、その中に入らないもの、
つまりは使わざるを得ない場合を紹介しよう。
どんな場合かというと、constを外しても、文字列を書き換えない場合だ。
文字列を書き換えないのになんでconstを外すのかというと、
本来ならばconst char*であるべきライブラリ関数の引数が、
何かの手違いや都合でchar*になっている場合である。
私は、この場合以外にconstを外すべき場合が思いつかない。
もしそのライブラリが自作のものならば、
ライブラリの方を修正し、引数の型をconst char*とするべきであろう。
だが、プログラムは自分のライブラリだけで動いているわけではない。
その典型的な例がSDKである。
例えば、LVITEM構造体を用いて、LVM_SETITEMメッセージを送るときである。
LVITEM構造体のメンバ変数pszTextは、LPTSTR型である。
よって、CString型の値をここに入れることは出来ない。
恐らくこの変数は、LVM_GETITEMメッセージを使うときのためにconstを外してあるのであろう。
しかし、LVM_SETITEMでは文字列を変更される恐れは無い。(おそらく)
よって、この場合はLPTSTRにキャストしても良い場合である。
事実MFCのCListCtrl::SetItem関数でもconstを外している。
他にも、RegQueryValueEx関数の第2引数lpValueNameの型がLPTSTRになっている。
そして、この関数はこのlpValueNameで渡された文字列を変更したりはしない。(おそらく)
正直、私には何でこの引数の型がLPCTSTRでないのか分からない。
不可解ではあるが、CString型の値をこの関数に渡したいと思ったとき困るのも事実である。
こんなときこそconst外しキャストの出番である。
こういった、文字列は変更されないけれどLPTSTR型がどうしても
必要な場合のみconstを外すべきである。
決して文字列を変更するためにconstを外してはならない。