mallocとwsprintfでString→charを確実に置換するには?

解決


鈴木  2007-06-24 08:28:43  No: 65477

初めて質問させて頂きます。
当方、とりあえずmallocの使い方は判ります(何故かfreeで落ちますが)。
環境はVC++2003.NETです。

class Convert_String{
private:
   char* Text;
public:
   char* ToChar( System::String* SetText ) {
      char* Text = (char*)malloc( SetText->Length );
      wsprintf( Text, TEXT"%s", SetText );

      return Text;
   }
   ~Convert_String() {
      free( text );
   }
};

以上が現在書いているクラスの内容です。これは

Convert_String* obj = new Convert_String;
char* GetText = obj->ToChar( S"フォームから取得したストリングクラスの文字列" );
free( obj );

と記述する事で簡易にフォームから取得されるString型の文字列をchar型へと動的に置換する事が目的です。

これで一応、SetText(Stringクラス)からText(char型)に変換されてGetTextへと渡ってはいるのですが、稀に文字列がコピーされずに壊れてしまい困っています。
forで百回回してウォッチ機能で調べた所、どうもwsprintfで置換されないでTextが"   "となる事がある事が判りました。

そもそもwsprintfでの置換が本で調べてとりあえず出来たから使ってる、と言う感じですので、何が悪いのかも判りません。
何方か、改善策をご教授下さい。宜しくお願いします。


Blue  2007-06-24 09:50:21  No: 65478

とりあえず、
>SetText->Length 
ではUnicodeでの文字数しか取得できません。

ですのでCP932(Shift_JIS)をあつかうchar型配列では
たとえば、

"あ"

という文字列はUnicodeでは1文字ですが、
char型配列で扱う上では('\0'を含み)3バイト必要になります。
よって、mallocした領域以上にwsprintfで文字を入れてしまうため
freeでエラーになるようになっているのです。
(本来ならばwsprintfでエラーになるべきですけど。)

Unicodeで扱っているSystem::Stringを
Shift_JISで扱うchar型配列に入れるには文字コード変換が
必須になります。

一般的にはEncodingクラスをつかったりMarshalクラスを使って
.NET Frameworkが用意しているクラスでchar*型に変換します。

Visual C++ .NET で System::String* から char* に変換する方法
http://support.microsoft.com/kb/311259/ja


鈴木  2007-06-25 03:35:37  No: 65479

Blueさん、質問にお答え頂き誠に有難う御座います。
リンク先の方法を試しましたところ、問題なく動作する事が出来ました。

また、freeで(実はちょっと前まではwsprintfでも)落ちる原因まで教えて頂き、誠に有難う御座いました。


RAPT  URL  2007-07-06 09:27:40  No: 65480

解決されたようだけど、せっかく C++ 使うなら、
malloc - free ではなく、new - delete を使うほうがお勧めです。
あと、メンバ変数(特にP.O.D.な変数)はコンストラクタで
初期化したほうが良いです。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加