MFCを使ってTOOLの開発をしています佐々木と申します。
MFCの経験は3ヶ月です。仕事をしながらMFCを学んでいます。
Cstring型の出力用バッファで質問があります。ご回答よろしく御願いいたします。
Cstring型の出力用バッファに複数の数値を受け取とり、
下記のように(出力したイメージを参照)表示したいのですが
上手くいきません。(例1、例2参照)
書式指定文字列の使い方が、C言語のprintfとは違うのでしょうか?
なお、均等間隔で表示する仕様は、
1、各数値は[この位置に合わせて表示する(例1参照)
2、余計な数値は出力してはいけない(例2参照)
[宣言と初期化部分]------------------
Cstring cs_disp;
int round1[2],round2[2],round3[2];
round1[0] = 1234567;
round2[0] = 12345;
round3[0] = 12345;
round1[1] = 123;
round2[1] = 123;
round3[1] = 123;
----------------------------------
問題となっている箇所
●出力したいイメージ
[RND1] [RND2][RND3]
1234567 12345 12345
123 123 123
●例1
[RND1] [RND2][RND3]
1234567 12345 12345
123 123 123
出力用バッファに格納する方法
→cs_disp.format(%7d %5d %5d,round1[0],round2[0],round3[0]);
●例2
[RND1] [RND2][RND3]
1234567 12345 12345
0000123 00123 00123
出力用バッファに格納する方法
→cs_disp.format(%7.7d %5.5d %5.5d,round1[1],round2[1],round3[1]);
以上、よろしく御願いいたします。
開発環境を追加させて頂きます
WindowsXP,VC++6.0,MFC
CstringがMFCのCStringであれば、書式指定文字として
-を指定すればいいです。
Cstringが自作クラスならばわかりません。
(MFCにはそんなクラスありませんので)
例)
#include <afx.h>
#include <iostream>
int main()
{
CString s;
s.Format( %-7d %-5d %-5d, 1234567, 12345, 12345 );
std::cout << static_cast< LPCTSTR >( s ) << std::endl;
s.Format( %-7d %-5d %-5d, 123, 123, 123 );
std::cout << static_cast< LPCTSTR >( s ) << std::endl;
return 0;
}
> 書式指定文字列の使い方が、C言語のprintfとは違うのでしょうか?
一緒だと思われます。
MSDNでCString::Format関数にも、
> 式は、printf 関数の書式引数と同じ機能を持っています。(書式や引数の説明は、
>『ランタイム ライブラリ リファレンス』の「printf」を参照してください)。
とあります。
TO:Blueさん
ご回答有難うございます。
書式指定文字として-を指定して出力画面を表示してみました。
しかし、出力画面は、例1と同じ表示です。
> 式は、printf 関数の書式引数と同じ機能を持っています。(書式や引数の説明は、
>『ランタイム ライブラリ リファレンス』の「printf」を参照してください)。
これで原因が書式文字列ではないことが分かりました。
>CstringがMFCのCStringであれば
この言葉が引っかかったため、Cstringの型を調べてみました。(デバックモード参照)
その結果、CStringがATLであることが判明致しました。
ATL自体が良く分からないため、この点は掘り下げれません。
ただ、デバックモードの値を見る限り、
複数の数値を等間隔で格納されていました。
私としては、文字のサイズが原因になっているのかなと考えています。
とりあえず、途中経過ですが報告させて頂きました。
●デバックモード(変数cs_disp[i])
値1234567 12345 12345
型ATL::CStringT<char,StrTraitMFC<char,ATL::ChTraitsCRT<char> > >
値123 123 123
型ATL::CStringT<char,StrTraitMFC<char,ATL::ChTraitsCRT<char> > >
●例1
[RND1] [RND2][RND3]
1234567 12345 12345
123 123 123
出力用バッファに格納する方法
→cs_disp[i].format(%-7d %-5d %-5d,round1[0],round2[0],round3[0]);
~~~
以上、ご指摘等ありましたら、よろしく御願いいたします。
ATL::CStringはMFCのCStringとほぼ一緒だとおもっていいとおもいますけど。
> この言葉が引っかかったため、Cstringの型を調べてみました。
> その結果、CStringがATLであることが判明致しました。
とは、どこかで
typedef ATL::CString Cstring;
または
#define Cstring ATL::CString
とでもしているのでしょうか?
> [RND1] [RND2][RND3]
> 1234567 12345 12345
> 123 123 123
はどのようにして確認されているのでしょうか?
TO:Blueさん
回答します。
> この言葉が引っかかったため、Cstringの型を調べてみました。
> その結果、CStringがATLであることが判明致しました。
とは、どこかで
→デバックモード(自動変数→型を確認)です。
また、Format→右クリック→定義へ移動でも確認できます。
ただ、ATL::CStringをファイル内の検索で探しても見つからないので、
私の勘違いかもしれません。
正直、この辺りもまだ良く分からないため、勉強が必要な部分です。
もし知っていましたら、ご教授願います。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> [RND1] [RND2][RND3]
> 1234567 12345 12345
> 123 123 123
はどのようにして確認されているのでしょうか?
Cstring型の変数で格納したものをTextOut関数で表示しています。
念のため、そのソースの一部を記載させて頂きます。
fn.CreateFont(フォントのサイズなど指定);(※1)
pFont = pDC->SelectObject(&fn);
pDC->TextOut(x,y,cs_disp[i],strlen(cs_disp[i]));
(※1)フォントのサイズが原因だと思いまして、CreateFont関数内の引数を
色々調べて修正してみましたら、下記のようにイメージ通り修正することができました。
[RND1] [RND2][RND3]
1234567 12345 12345
123 123 123
以上です。BLUEさん本当に有難うございました。
(また、波線(~~~)の回答を待ってから
解決ボタンをチェックさせて頂きます。)
ATL::CStringについての説明の追加と補足をします。
>とは、どこかで
>typedef ATL::CString Cstring;
>または
>#define Cstring ATL::CString
>とでもしているのでしょうか?
どちらもしていません。
また、Format→右クリック→定義へ移動でも確認できます。
このように説明してしまいましたが、定義へ移動してしまうと
下記のようなソースになっていて、実際に確認できたわけではありません。
ただ、定義へ移動(あいまいさの解決)の選択肢には、
ATL::CStringT<BaseType,StringTraits>::Format(PCXSTR pszFormat,...)-
C\Program File\Micorsoft(省略)\(省略)
このようになっています。
●定義へ移動後のソース
void __cdecl Format( PCXSTR pszFormat, ... )
{
ATLASSERT( AtlIsValidString( pszFormat ) );
va_list argList;
va_start( argList, pszFormat );
FormatV( pszFormat, argList );
va_end( argList );
}
以上です。
Blue さんが書かれているのは、
MFC の文字列型は CString で、佐々木晋二 さんの書かれているのはCstring、
'S'と's'が違うということだと思いますが。(C++ は大文字/小文字を区別する言語です)
ところで、お使いの VCのバージョンは何ですか。
VC++.NET2002, VC++.NET2003等、MFC7以降では CString の実装が template になり、
ATL と統合されてます。
# MFC 専用の CString ってのはなくなったというか、他と切り離して使えるようになっ
た。
> ただ、ATL::CStringをファイル内の検索で探しても見つからないので、
ご自身のヘッダではなく、VC のヘッダ内を検索されているなら、
grep のかけ方次第では見つからないと思います。
<afxstr.h>
typedef ATL::CStringT< wchar_t, StrTraitMFC< wchar_t > > CStringW;
typedef ATL::CStringT< char, StrTraitMFC< char > > CStringA;
typedef ATL::CStringT< TCHAR, StrTraitMFC< TCHAR > > CString;
</afxstr.h>
> 開発環境を追加させて頂きます
> WindowsXP,VC++6.0,MFC
見落としてました....orz
TO:Banさん
ご回答ありがとうございます。
>'S'と's'が違うということだと思いますが。(C++ は大文字/小文字を区別する言語です)
お恥ずかしいのですが、意識していませんでした。
私は基本が全然分かっていないようです。。。
>VC++.NET2002, VC++.NET2003等、MFC7以降では CString の実装が template になり、
>ATL と統合されてます。
># MFC 専用の CString ってのはなくなったというか、他と切り離して使えるようになっ
>た。
開発環境というのが、そこまで左右されるものとは知りませんでした。
デバックモードで確認した開発環境は、VC++.NET2002です。。。。
今後、開発環境には、使用している開発環境を全て書かせて頂きます。
>> ただ、ATL::CStringをファイル内の検索で探しても見つからないので、
>ご自身のヘッダではなく、VC のヘッダ内を検索されているなら、
>grep のかけ方次第では見つからないと思います。
>見落としてました....orz
申し訳ございません、以後冒頭に記載させて頂きます....orz
以上です。Blueさん、Banさん 本当に有難うございました。
お陰さまで解決することができました。
> 開発環境を追加させて頂きます
> WindowsXP,VC++6.0,MFC
> デバックモードで確認した開発環境は、VC++.NET2002です。。。。
どおりで、わからなかったわけです。
(私の環境はVC6で試していましたから。)
ところで、VC6でつくって、デバッグはVC2002ってめんどくさくないですか?
> お恥ずかしいのですが、意識していませんでした。
format とかも小文字になってましたので(MFCの場合はFormat)、
転記ミスではなく「よく似せた自作クラス」かな、という風にも見えました。
それで Blue さんにも以下のように書かれたのだと思います。
> CstringがMFCのCStringであれば、
TO:Blueさん
回答します。
>ところで、VC6でつくって、デバッグはVC2002ってめんどくさくないですか?
デバックをするために開発環境をかえているわけではありません。
職場の開発環境がVC6で、自宅の開発環境がVC2002しかないため、
職場で気になった箇所を自宅でテストする時は、
デバックをVC2002でせざる得ないのです。
TO:Banさん
>format とかも小文字になってましたので(MFCの場合はFormat)、
>転記ミスではなく「よく似せた自作クラス」かな、という風にも見えました。
>それで Blue さんにも以下のように書かれたのだと思います。
>> CstringがMFCのCStringであれば、
なるほど、無知は罪ですね。。。
基本からしっかり学ぼうと思います。