• ベストアンサー

初歩的なんですが…

自分の母語はJavaなのですが、先日C++を始めました。 やっぱり似ているのでスイスイいけてはいたのですが 初歩的な所でつっかかりました… 自分でも調べたのですが、できないのかを調べるのことは難しくて… よかったら教えてください。。 Javaでは、例えば、 Method(String str, int num) で定義されたメソッドを呼ぶとき( aはint型の変数として適当な値が入っているとして) Method("文字" + a, 99); という感じで呼べます。≪"文字" + a≫が文字列として扱われるからなのですが、、 C++はこうゆうことができないのでしょうか? やりたいことを具体的に書きますと、 BOOL TextOut( HDC hdc, // デバイスコンテキストのハンドル int nXStart, // 開始位置(基準点)の x 座標 int nYStart, // 開始位置(基準点)の y 座標 LPCTSTR lpString, // 文字列 int cbString // 文字数 ); を呼ぶときに、 TextOut(hdc, 0, 0, a + "回", 3); という感じで呼びたいのですがもちろんダメです。 調べたところ、 wsprintf()を使って一旦別の変数に入れるという段階的な方法が見つかりました。でもこれだとなんかスマートな感じがしなくて、変数も消費してしまいますし… ダイレクトでJavaのようにすることはできないのでしょうか? 何かこういった場合に使える演算子などありませんでしょうか?

  • siois
  • お礼率60% (53/88)

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

  • ベストアンサー
  • noocyte
  • ベストアンサー率58% (171/291)
回答No.3

回答ではありませんが,一応ご参考まで. > Method("文字" + a, 99); ↑は, Method(new StringBuffer().append("文字").append(a).toString(), 99); と同等なコードとしてコンパイルされるそうです(↓). クラス StringBuffer http://sdc.sun.co.jp/java/docs/j2se/1.4/ja/docs/ja/api/java/lang/StringBuffer.html なので, > wsprintf()を使って一旦別の変数に入れるという段階的な方法が見つかりました。 > でもこれだとなんかスマートな感じがしなくて、 確かにスマートではありませんが,やってる処理内容はほぼ同じで, プログラマが自分で書くか,コンパイラがこっそり変換するかの違いだけ. > 変数も消費してしまいますし… Java だと「変数」は消費しなくても,「StringBuffer オブジェクト」は 消費 (使い捨て) してますよね.

siois
質問者

お礼

>Method(new StringBuffer().append("文字").append(a).toString(), 99); なるほど… 確かにコンパイラがやってたら、せっかく節約しても意味がないかもしれませんね。。 貴重なご意見ありがとうございました。

その他の回答 (4)

  • jacta
  • ベストアンサー率26% (845/3158)
回答No.5

> Method("文字" + a, 99); この方法だと、aを16進で表記したいとか、桁をそろえたいとか、ちょっと凝ったことをしようとすると記法が変わってしまいますね。 #4の回答で取り上げられている「Exceptional C++ Style」での結論についてもう少し詳しく書くと、 1. 文字列に変換するだけであれば、デフォルトでboost::lexical_castを使う。 2. 単純なフォーマットで、テンプレート化が必要な場合は、std::stringstreamまたはstd::strstreamを使う。 3. 複雑なフォーマットで、テンプレート化が不要な場合はstd::tr1::snprintfを使う。 4. パフォーマンスが問題となる場合は、std::strstreamかstd::tr1::snprintfのうち、実測しか結果がよい方を使う。 5. std::sprintfは使うべきではない。 といったところです。 ただし、Boost C++ Librariesが使えない場合、1.の選択肢はなくなりますし、逆に、使える場合には、boost::formatも候補として上がってきます。また、std::tr1::snprintfは、少なくとも現時点では標準ではありませんし、実際に使えない環境も多いので、選択肢から外さざるを得ない場合も多いと思います。なお、std::tr1::snprintf関数のワイド文字版であるstd::swprintf関数であれば現時点でも標準関数です。 C++では、状況に応じて最適な方法を使い分けるのが基本です。常に便利な方法を使うとなれば、もっとも汎用的だけれども、もっとも重量級の方法として実装せざるを得ず、機能要件は満たせても、非機能要件を満たせなくなる可能性があるからです。

siois
質問者

お礼

なかなか難しいお話ですね… でも、 >C++では、状況に応じて最適な方法を使い分けるのが基本です。 >常に便利な方法を使うとなれば、もっとも汎用的だけれども、 >もっとも重量級の方法として実装せざるを得ず、機能要件は >満たせても、非機能要件を満たせなくなる可能性があるからです。 ここは納得できます。 自分の中の固定観念を捨てて、柔軟に色々な方法を取り入れていきたいと思います。 どうもありがとうございました。

  • lv4u
  • ベストアンサー率27% (1862/6715)
回答No.4

C++を開始して悩む個所は、私と同じですね。同僚もC#を始めたときに、数字-->文字変換で悩んだと言っていました。 「Exceptional C++ Style」を読むと、この問題は17ページにもわたるページを費やして議論されています。 議論の中心は「C言語の使いやすいけど危ないsprintf系と、安全だけど使いずらいC++系のstream系あるいはboostのlexical_castを使うか?」って議論です。 この議論の中に、「sprintfを使うなら、より安全なsnprintfを使うように」ってありました。で、私はC++のやり方にこだわるより、判り易さ優先ってことで、sprintfの代わりに、手軽なsnprintfをとりあえず使っています。 それからダイレクト(自動的)な数字-->文字変換って、C言語からやってきた人にとっては、可能かもしれないけど、ちょっと違和感を感じてしまうところもあります。また、それ以上に見やすいフォーマットで出したいという理由もあって、出力前に、事前にsnprintfでフォーマットしています。

siois
質問者

お礼

同じところで悩んだ方がいらっしゃるとわかって安心しました。。 やっぱり違う言葉なのだから、自分の中のデフォルトも 変えていかなきゃならないのでしょうかね? C++ではそれが普通なんだと思えるように頑張りたいと思います。。 どうもありがとうございました。

  • rabbit_cat
  • ベストアンサー率40% (829/2062)
回答No.2

MFCのCString::Format()とか、 boost::formatとか、 std::ostringstreamとか でしょうか。

siois
質問者

お礼

すみません、、ちょっとわかりませんでした。 もっと自分のレベルが上がったときに参考にしたいと思います。 ありがとうございました。

  • koko_u_
  • ベストアンサー率18% (459/2509)
回答No.1

C++ というか MFC なら CString を使えば良い。 その場合 CDC::TextOut(int x, int y, const CString&) を使う。

siois
質問者

お礼

色々やってはみたのですが、どうもまだ自分には早いようで うまくできませんでした…せっかくなのにすみません ありがとうございました。

関連するQ&A

  • C++のwindowsアプリケーションについて

    windowsアプリケーションで 数字を表示させたいのですができません。 文字列に置き換えないといけないみたいなのですが。なかなかうまくいきませんでした。 :上省略: case WM_PAINT: hdc = BeginPaint(hWnd, &ps); // TODO: 描画コードをここに追加してください... int a; a=10; char buf[10]; sprintf(buf,"%d",a); TextOut(hdc,100,20,L"Hello Window!",13); TextOut(hdc,100,50,L"buf",10); としたのですが Hello Window!は表示されるのですが  そのしたに10と表示させるにはどうしたらよいでしょうか?? #include <stdio.h>は上に書いてあります。 詳しい解説よろしくお願いします。

  • DrawTextで文字を表示する場合の引数

    バイナリファイルを読み込んで文字列を表示しようとしています。 表示する位置の座標をx,y変数に取っていて、TextOutならば、そのまま 引数として渡せるのですが、DrawTextの引数はRECTポインタなので、 メンバが4つありますし、どのメンバにxとyを当てればよいかわかりません。 何パターンかやってみたのですが、正しいのがわからず困っています。 初歩的な質問だったらすみません。どなたか教えてください。

  • BeginPaintの使い方

    現在windowsプログラミングを勉強しています。 まだまだはじめたばかりでwindowsプログラミングの把握できていない部分が多々あるので、何か使い方が根本的に間違えているところがあるかもしれませんが、ご容赦ください。 case WM_PAINT: hdc=BeginPaint(hdc,&ps);/*rc,hdc等は宣言済み*/ TextOut(hdc,0,0,szStr,(int)strlen(szStr));/*szStr="文字列"代入済み*/ EndPaint(hWnd,&ps);/*hWnd等は宣言済み*/ break; において、 1.ダブルクリックしたら表示させよう!と思いまして、 WM_PAINT→WM_RBUTTONDBLCLKSと変更したところ表示されなくなりました。 しかし、hdc取得をGetDCで行うとうまくいきました。この違いがよくわかりません。 2.次はダブルクリックすると文字を右に動かそう!と思いまして、 TextOut(hdc,i,0,・・・・)などといたしましてiを増やしたところ更新前の画像が残りました。そこでInvalidateRectによって背景消去しようとおもいまして、TextOutの前に挿入しましたがこれによっても初めから、クリック後も何も表示されなくなりました。 1と2の2点に関して、どなたかご教授いただけないでしょうか。よろしくお願いします。

  • 漢字英数字混在のANSI文字列のデェジット分解法?

    lpStringに漢字のANSI文字列が入っています 漢字ですので2バイト構成になっています その2バイトの先頭digit、2番目のdigit、3番目のdigit、最後のdigitを順次取り出します for (int i = 0; i<strlen(lpString); i++) { unsigned int TopDigit = lpString[i]; TopDigit = TopDigit >> 12; TopDigit = TopDigit & 0x000f; unsigned int SecondDigit = lpString[i]; TopDigit = TopDigit >> 8; SecondDigit = SecondDigit & 0x000f; unsigned int ThirdDigit = lpString[i]; ThirdDigit = ThirdDigit >> 4; ThirdDigit = ThirdDigit & 0x000f; unsigned int LastDigit = lpString[i]; LastDigit = LastDigit & 0x000f; 以下の処理は省略     } i<strlen(lpString)により文字列中の全文字をdigitに分解しております ここでハテ? なんです もし文字列の中に1バイト文字の英数字が含まれていたらどうなりますか? 漢字コードのdigit分解もこれで良いのでしょうか? int WORD = lpString[i] は漢字コードの時は2バイト、英数字の時は下バイトに1バイトが入るのでしょうか? 我ながらANSIコードの特性が分かっていないと思っています 漢字英数字混在の文字列のデェジット分解法をご教授願います

  • c#のToString()メソッド

    http://msdn.microsoft.com/ja-jp/library/ms173154(v=vs.90).aspx のページによると C# では、すべてのオブジェクトが ToString メソッドを継承します。このメソッドは、該当するオブジェクトの文字列形式を返します。たとえば、int 型の変数はすべて ToString メソッドを持ち、次のようにその変数の内容を文字列として返すことができます ↑と書いてあるのですが、C言語しか知らない自分にとってint型の変数が関数、メソッドを持つ、 という概念が理解できません。これはオブジェクト指向の話なのでしょうか?クラスを理解すると わかるようになりますか? どなたかよろしくお願いします。

  • VCのTextOutについて

     TextOutは、文字を描画するやつですよね? たとえば、  a=80 というのがあった場合、80%と描画したい場合どうしたらいいですか? TextOut(hDC,100,100,a"%",10)としたらエラーになります。 さっきの質問もなんですけど、こっちは急いでるんで、早く回答ください (怒) まじで・・・。

  • StretchDIBits

    StretchDIBits()のxSrc, について質問なんですが この座標は, 画面の左下,左はしを(0,0) を基準としているんですか? 普通の関数の座標基準点とは上下逆になっているんですか? int StretchDIBits( HDC hdc, int XDest , int YDest , int nDestWidth , int nDestHeight , int XSrc , int YSrc , int nSrcWidth , int nSrcHeight , CONST VOID *lpBits, CONST BITMAPINFO *lpBitsInfo, UINT iUsage , DWORD dwRop );

  • プリンターであるか否かの判断?

    特殊な目的の為、文字列変数Deviceを受取りその内容がプリンターを示すものであれば、APIのCreatDCでプリンターのHDCを作成します そしてそのプリンターのHDCを使用してStartDoc、StartPage、Textout等の一連の印刷動作をしたいと思います それには先ず文字列変数Deviceの内容がプリンターを示しているか? を判別しなくてはなりません 色々調べましたら WINSPOOL である場合はプリンターです 内容が NULL(空白)であればプリンターと判断すべきらしいです また内容が "ディスプレイ" ならば当然除外します しかしこんな判定法で宜しいのでしょうか? 特に文字列変数Deviceの内容が、コントロールパネル⇒デバイスとプリンター によって表示される Canon MP280 series Printer などの具体的なプリンター名称であった場合不安です 文字列変数Deviceの内容がプリンターを示しているか否かを判定するAPIなどはありませんが? また他の手段で簡単に判別する方法をご存知でしたら教えて下さい 宜しくお願い申し上げます

  • C言語で文字列バッファを消去する方法

    今、C言語とWin32 APIを使ってプログラミングをしています。 wsprintf(str,TEXT("プレイヤーの攻撃!")); TextOut(hdc,0,520,bstr,lstrlen(str)); if(ehp <= 0) {    wsprintf(str,TEXT("敵を倒しました"));    TextOut(hdc,0,520,bstr,lstrlen(str)); } このコードを実行すると、2回目のTextOutのところで 「敵をたおしました撃!」と出てしまいます。 きっとstrに以前の文字列が残っているからだと思いますが、 この保存した文字列を消去するにはどうしたらよいのでしょうか? for文でstr[0]から'\0'までナル文字を代入し続けたり、いろいろと試したのですが駄目でした。どうかこんな自分にご助力お願いできないでしょうか? どうかお願い致します。

  • wParam

    wParamは、unsigned int型で、仮想キーコードを、格納してますよね。 wsprintf()内で(TCHAR)キャストしてますが、 これは、変数strの型がTCHAR型なので(wParamは、unsigned intなので型をあわせるために)やっているんですか? (TCHAR)キャストしないとエラーになりますか?教えてください。 HDC hdc; TCHAR str[255]; swich(umsg){   case WM_CHAR:     wsprintf( str, TEXT("%c"), (TCHAR)wPara );     hdc = GetDC(hwnd);     TextOut(hdc, 0, 0, str, lstrlen(str));     return0 }

専門家に質問してみよう