マルチバイト文字セットで wchar_t 系の関数にセットする方法

このQ&Aのポイント
  • VisualStudioでマルチバイト文字セットを使用する設定のプロジェクトで wchar_t をパラメータとする関数に文字列をセットする方法について説明します。
  • マルチバイト設定では、wchar_t 系の関数に文字列を渡すとエラーが発生しますが、UNICODE文字セットを使用すれば問題ありません。
  • プロジェクトがマルチバイト設定の場合でも、UNICODEとマルチバイトの両方に対応する方法があります。
回答を見る
  • ベストアンサー

定義した文字列を wchar_t 系の関数へ

こんにちは。 VisualStudioでマルチバイト文字セットを使用する設定のプロジェクトで、下記のように定義された文字列を wchar_t をパラメータとする関数にセットするにはどのようにすればよろしいのでしょうか? #define _FOO "foo" void funcA( const char* const szValue ) { } void funcW( const wchar_t* const szValue ) { } void test( void ) { funcA( TEXT( FOO )) ; ← ok。 funcW( TEXT( FOO )) ; ← エラー。 } UNICODE文字セットを使用する設定のプロジェクトならば問題ないのですが、マルチバイト設定ですとエラーになってしまいます。UNICODE、マルチバイト両方にプロジェクトに対応できるにはどうきじゅつすればよろしいのでしょうか。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.2

> funcW( TEXT( FOO )) ; ← エラー。 funcW( (const wchar_t*)(TEXT( FOO ))) ; ではないかな。 TEXT( FOO )がconst char *を返してるから > funcA( TEXT( FOO )) ; ← ok。 なんですよね。

TeijigoTeatime
質問者

お礼

saijyo_739 さん、ご返答ありがとうございます。 強制的に型を変換する方法ですね。これならうまくいきそうです。 いろいろ試してみます。ありがとうございます。

その他の回答 (2)

回答No.3

> プロジェクトがマルチバイト設定の場合に、強制的に > > funcW( _FOO ) > > でコンパイルが通るようにしたいのですが、wchar_t に強制的に型変換したほうがよろしいでしょうか。 なにがしたいのかさっぱりわからんです。 #define _FOO "foo" なんだから funcW(_FOO) が通るなら void funcW(const char* szValue) ってことでしょ。 だったら void funcW(const char* szValue) { ... } と void funcW(const wchar_t* szValue) { ... } を定義しとけばいいんでないの? C++なら。

TeijigoTeatime
質問者

お礼

episteme さん、ご返答ありがとうございます。 うまく説明できてなかったようで申し訳ありません。 C++自体の理解が足りなかったようです。 関数のオーバロードでいろいろ試してみます。 ありがとうございます。

回答No.1

C++ なら関数オーバロードで: void func( const char* const szValue ) // char-version { } void func( const wchar_t* const szValue ) // wchar_t-version { } void test( void ) { func("FOO") ; // char-version called func(L"FOO"); // wchar_t-version called }

TeijigoTeatime
質問者

お礼

episteme さん、ご返答ありがとうございます。オーバロードするというのは理解できました。もし、 #define _FOO "foo" と定義されていた場合で記述するにはどうすればよろしいのでしょうか ? プロジェクトがマルチバイト設定の場合に、強制的に funcW( _FOO ) でコンパイルが通るようにしたいのですが、wchar_t に強制的に型変換したほうがよろしいでしょうか。 p.s. サンプルで書いたころに FOO は _FOO の誤りです。失礼いたしました。

関連するQ&A

  • ワイド文字列とコンストラクタ

    ワイド文字列(UNICODE)をクラス化しようとしているのですが、 コンストラクタにconst wchar_t*型の引数を持たせて呼び出すと、 コンストラクタに渡された文字列が消えてしまい、wcslen()でサイズを求めると何故かサイズも0になっています。 class WideString { public: WideString(const wchar_t*); … }; WideString::WideString(const wchar_t* ws) { ::OutputDebugString(ws); // ←文字列が消えてる?表示されない int len = wcslen(ws); // ←これが0 } int main(void) { WideString wStr(L"文字列"); … } これは一体どういうことなのでしょうか。どなたか教えてください。

  • visual studio2010 文字コード

    visual studio2010を使っています。Cのプログラムを書いてます。 文字セットを選ぶ箇所で ・マルチバイト文字セットを使用する ・Unicode文字セットを使用する という2つの選択肢がありますが、 上を選ぶとshift-jisの文字コードが選ばれると認識してます。 それで、下のUnicode文字セットを使用するを選んだ場合なんですが、 これはutf-16のことですか? utf-8が主流だと思っていたのでここでさすUnicodeが勝手に utf-8のことだと思ってたんですが、 visual studioで扱っている方はワイド文字で、 utf-8について調べたらASCIIにも対応できる可変長のマルチバイト という風に書いてあったので、あれ?と思い色々調べたら ウィンドウズではメモ帳などでUnicodeという表記でutf-16を指すみたいなので これも同じでutf-16なのかなと思いました。 ただ、visual studioで扱うUnicodeはワイド文字ということと、 utf-16は2バイト固定ではなく2バイト単位なだけで 4バイトで1文字を表すこともあることが書いてあったので、 これはワイド文字とは違う??と混乱してます。 それともワイド文字は2バイト固定と思ってたんですが wchar_tが2バイトずつなだけでワイド文字は1文字2バイトというわけではない ということでしょうか? それとwchar_tで2個分で1文字を表したりする使い方はするんでしょうか? まとまりのない質問になってしまいましたがよろしくおねがいします。

  • VC++ マルチバイト文字とUniCode文字??

    VC++のプロジェクトプロパティには文字セット指定があります 『マルチバイト文字セット』『UniCode文字セット』の2者が選択出来ますが、これらの選択の優劣は何処にありますか? この選択の適否が分からない私は参考にしているサンプルがマルチバイトである時にはマルチバイトを、またUniCodeで書かれたサンプルを見ている際にはUniCodeを指定しており、恥ずかしいかぎりです 選択の判断基準を如何すれば良いのかご指導をお願い申し上げます 更に恥ずかしい質問】なぜC#には文字セット指定が見当たらないのでしようか???

  • 関数名の名前の衝突について。

    こんにちは。 関数名の名前の衝突で困っています。 以下のような感じで名前空間でUNICODEでマルチバイト版とで定義しています。 Win32APIのGetFileSize関数を例に説明します。 Win32APIのGetFileSize関数はファイルハンドルを指定しなければいけないので 直接ファイル名からファイルサイズを取得できるように同じ名前の関数を 名前空間で区切って以下のようにしました。 ---------------- Foo.h -------------- #include <windows.h> namespace Foo { #ifdef UNICODE     #define GetFileSize GetFileSizeW #else     #define GetFileSize GetFileSizeA #endif // !UNICODE     DWORD GetFileSizeW( wchar_t* const szFilename ){ return 0 ;}     DWORD GetFileSizeA( char* const szFilename ){ return 0 ;} } ---------------- Foo.h -------------- 上記の関数はちゃんと動作することは確認できましたが、本来のWin32APIの DWORD GetFileSize( HANDLE hFile, LPDWORD lpFileSizeHigh ) を ---------------- main.cpp -------------- #include <windows.h> #include "Foo.h" void func( HANDLE hFile ) {     DWORD dwFilesize = ::GetFileSize( hFile, NULL ) ; } ---------------- main.cpp -------------- 上記のように利用しようとすると、 error C2039: 'GetFileSizeW' : '`global namespace'' のメンバではありません。 error C3861: 'GetFileSizeW': 識別子が見つかりませんでした というエラーが出てきてしまいます。 これを解決するためにはUNICODEでマルチバイト版とで再定義してしまっている #defineの部分を削除するしかないのでしょうか? もし解決方法がありましたら教えていただけないでしょうか?

  • ファイルの入出力でのテキスト モードでの変換について

    今までとりあえずサクサク骨組み作りたいので、短くかけるためマルチバイト文字主体で来たのですが ここらへんでUnicode文字のことが気になってきたので、以下のような関数を基本にしてプロパティやコードをいじったりしつつ入出力を色々試してみたのですが… (エラー時の処理とか省略します。) #include <TCHAR.h> #include <stdio.h> #include <locale.h> #ifdef _UNICODE #define 文字セット "Unicodeを使用" #else #define 文字セット "マルチバイトを使用" #endif void f(){ _tsetlocale(LC_ALL, _T("japanese")); FILE *fp; if ( _tfopen_s( &fp, _T("exp.txt"), _T("wb") ) ) return; _ftprintf( fp ,_T(文字セット)); fclose(fp); } ファイルサイズや出力内容を見てみると、Unicode文字を使う場合、このようにバイナリモードで書き込みをすると、バイト数が、単純にsizeof(wchar_t)*文字数になってしまうようで 気になったので調べてみると、こういうことみたいですね。 http://msdn.microsoft.com/ja-jp/library/c4cy2b8e%28VS.80%29.aspx 最後の方に >Unicode ストリーム入出力関数をバイナリ モードで実行すると、ファイルが Unicode であると想定されるため、入出力時に CR-LF 変換も文字変換も行われません。 と書いてありますが これは、ただしつまり Unicodeを扱う場合でも、結局バイナリモードで出力したらバイナリモードで入力すれば正しい同じデータが得られるし、テキストモードで出力したらテキストモードで入力すれば大丈夫と考えて良いですよね? 言い換えれば、少なくともUnicodeでテキストモードだと、CR-LF 変換と文字変換が行われてしまうということで (少なくともマルチバイトなら文字変換はなしでしょうが) 「文字変換」については今回初めて知りました。 他にはマルチバイト・Unicode問わず、テキストモードを使用すると、何か変換が行われる可能性はあるのでしょうか?

  • 文字のバイト数を数えるには

    なんか一日一問になってしまったのですが、、 よろしくお願いします。 wchar_t 型に入っている文字のバイト数を数えるにはどうしたら良いでしょうか? L"あいう123" のような文字の場合UNICODEの場合12バイトですが、 全角半角区別して9バイトを求めたいです。 UNICODE環境では不可能でしょうか?

  • 自作ライブラリとプロジェクトの文字セットによる文字化けについて

    お世話になります。 今回自作ライブラリ内にある、ウインドウ作成補助関数をUnicode、マルチバイト文字両対応にするべく作業を進めていたのですが、ある所でどうしても上手く行かず、どうしたものかと困っております。 概要は下記の通りです。 1. Unicode用関数とマルチバイト用関数は分けれらており、UNICODEマクロの有無によって使用する関数を自動的にわけています。 2. 自作ライブラリをUnicode文字セットでビルドし、ライブラリを使用するプロジェクトをマルチバイト文字セットでビルドした場合、ライブラリ内ウインドウ作成クラスから関数を利用してウインドウを作成すると、どうしてもタイトルバーのタイトルに文字化けが起こってしまう。 以下に要点だけをまとめたソースを記載させていただきます。 文字数の関係で、リンクとなってしまい申し訳ありません。 http://blog-imgs-26.fc2.com/b/a/l/balmysoft/CreateWindow.txt プロジェクトでの使用法は INT WINAPI WinMain( HINSTANCE hInst,HINSTANCE hPrevInst,LPSTR szStr,INT iCmdShow) { CCreateWindow cw; cw.SimpleCreateWindow( _T("HelloWorld"), その他いろいろ... ); // その後の処理 // } このような形です。 ライブラリとの文字セットとの違いを考慮し、関数を分けて使い分けているのですが、実際にウインドウが作成されてみると、タイトルバーのタイトルが文字化けをしてしまっています。 また、関数内でもそれぞれの文字セット用の関数を呼び出しているつもりなのですが、これだけでは至らないのでしょうか? もちろんプロジェクト側の文字セットをUnicodeにすれば大丈夫です。 また、ライブラリ側をマルチバイト文字セット、プロジェクト側をUnicodeにすると、先頭の一文字だけがタイトルバーに表示されます。 今回の場合は H  だけとなります。 これはワイド文字だからその通りの結果だと思うのですが、今回疑問に思っているのは。 WindowsAPI である CreateWindowA や CreateWindowW を使い分けても、実際はそのプロジェクトの文字設定によって影響されてしまうのか。 ということです。また、これを避ける手立てはあるのでしょうか? 長くなってしまい、大変申し訳ありません。 もしよろしければ、どなたか御教示頂けませんでしょうか。 宜しくお願い致します。

  • VC++2005で、CString型に16進文字列を入れたいのですが・・

    VC++2005で、CString型に16進文字列を入れたいのですが・・・ 次のようなエラーが出ます。 void ATL::CStringT<BaseType,StringTraits>::Format(const wchar_t *,...)' : 1 番目の引数を 'const char [5]' から 'const wchar_t *' に変換できません。 プログラムは次の通りです。 CString strBuff; CString strWork; TCHAR tszBuff[80]; UINT unLength; UINT un1; unLength = 5; strBuff = "12345"; _tcscpy(tszBuff, strBuff); strWork = ""; for(un1 = 0; un1 < unLength; un1++) { strWork = strWork + strBuff.Format("%02x", tszBuff[un1]); ←ここにエラーがあると言われています。 } 結果は、strWorkに、"3132333435"となるようにしたい! ネットで探したら、 >UNICODEを使われているのだと思われます。 >T("")マクロを使ってワイドキャラクタに変換するように指示すれば動くと思います。 とあったので、 strWork = strWork + strBuff.Format(_T("%02x"), tszBuff[un1]); としてみたのですが、 二項演算子 '+' : 型 'void' の右オペランドを扱う演算子が見つかりません (または変換できません)。 というエラーが表示されました。 VC++6.0を半年かじり、今日、初めてVC++2005に触った程度の初心者です。 どなたか助言を頂ければ幸いです。 環境  Windows XP Pro SP3  Visual C++ 2005(MFC) 以上、よろしくお願いします。

  • MFC:リッチエディットからUnicode文字列を受け取りたい

    MFCのダイアログベースでプロジェクトを作成 ↓ プロジェクトのプロパティで「マルチバイト文字セットを使用する」を「Unicode文字セットを使用する」に変更 ↓ エディットボックスとリッチエディット2.0を適当に配置 ↓ エディットボックスとリッチエディット2.0それぞれにコントロール変数を追加 ↓ InitInstance()内に AfxInitRichEdit2(); を追加 ↓ あとは適当なところでエディットボックスとリッチエディット2.0それぞれにGetWindowText関数を使って、記入内容を取得します。     すると、エディットボックスではUnicodeの文字を入れても文字化けしないのに対し、リッチエディット2.0では文字化けしてしまいます。 例えば“Å”の半角文字を(Unicode紹介サイトからコピペする等して)入力すると、エディットボックスではそのまま“Å”なのに、リッチエディット2.0では“A”になります。   ※入力している段階では“Å”と表示されています。GetWindowText関数で取得すると“A”になってしまいます。     リッチエディット2.0からUnicode文字を正常に受け取れる方法はありませんでしょうか。

  • 自作ライブラリの文字セットを両対応にしたが、上手くいかない

    前回質問させて頂いたのですが、こちらの不手際でソース内容の不十分や誤字や脱字が目立ちましたので、再度質問をさせて頂きます。申し訳ありません。 今回自作ライブラリ内に、ウインドウ作成補助用クラスを作成したいと思っております。 そこでUnicode、マルチバイト文字両対応にするべく作業を進めていたのですが、ある所でどうしても上手く行かず、どうしたものかと困っております。 自作ライブラリは静的リンクですので、dllの形ではありません。 概要は以下の通りです。 1. Unicode用関数とマルチバイト用関数は分けれらており、UNICODEマクロの有無によって使用する関数を自動的にわけています。 2. 自作ライブラリと、それを使用するプロジェクト側の文字セットが違うと、それぞれ上手くいかない。 ライブラリがUnicodeセット、使用するプロジェクトがマルチバイトだと文字化け。 ライブラリがマルチバイト、使用するプロジェクトがUnicodeセットだとchar型と認識されて2文字目にNULLが入り、1文字しか表示されない。 3. ブレークを当てると、使用するプロジェクト側の文字セットに合った関数にはちゃんと飛んでいます。 以下文字数の関係から、ソースURLを記載させて頂きます。 全文ですので多少冗長になってしまいますが、宜しくお願い致します。 ヘッダー http://blog-imgs-26.fc2.com/b/a/l/balmysoft/CreateWindowh.txt 実装部 http://blog-imgs-26.fc2.com/b/a/l/balmysoft/CreateWindowcpp.txt プロジェクトでの使用法は INT WINAPI WinMain( HINSTANCE hInst,HINSTANCE hPrevInst,LPSTR szStr,INT iCmdShow) { HWND hWnd; BalmyWindows::CCreateWindow cw; cw.SimpleCreateWindow( &hWnd, hInst, 0, 0, 640, 480, false, _T("Hello"), NULL, NULL ); } このような形です。 これだけでは思い描いた形には至らないのでしょうか? もちろんプロジェクト側とライブラリ側との文字セットを同一にすれば上手くいきます ライブラリとそれを使用するプロジェクトの文字セットが違ってしまうと、上手くいかないようです。 ライブラリを作成した時点でWindowsAPI側がUNICODEマクロの影響を受け、静的に固定されてしまうものなのでしょうか? あまりコアな部分は詳しくなく、分からないのですが、APIであるCreateWindowを明示的にCreateWindowWやCreateWindowAなどと使いわけているのに上手くいかないのは疑問です。。。 どうにか、この問題を避ける手立てはあるのでしょうか? 長くなってしまい、大変申し訳ありません。 もしよろしければ、どなたか御教示頂けませんでしょうか。 何卒、宜しくお願い致します。

専門家に質問してみよう