お久しぶりでございます、アメヒルネというものです。
本日お尋ねしたいのは、簡単に言いますと「printfを別の関数を経由して実行する」というようなものです。
わかりやすいように例を書きます(実際にわかりやすいかは知りませんが)。
要するに、printfを「別の関数を経由して」動作させる、というようなものです。
実際にどういった原理を用いてprintfのような処理が行われているのかが分かりませんので、
そこをできれば教えていただきたく思います。
尚、使用している言語はC言語です。
タイトルではDrawFormatStringToHandle関数というDXライブラリの関数を用いておりますが、
実際に知りたいところはそこではなく書式付き文字列の表示の仕方なので、
なにとぞよろしくお願いいたします。
DrawFormatStringToHandle関数を拡張(?)したい
DrawFormatStringToHandle関数を拡張(?)したい
ほら、来いよ!! 誤字や矛盾を指摘したい奴から、前に出てこいよぉおおおおおおおッ!!!
※都合により、不定期でしか現れません。即返などはできませんのでご了承ください※
※都合により、不定期でしか現れません。即返などはできませんのでご了承ください※
- Dixq (管理人)
- 管理人
- 記事: 1661
- 登録日時: 13年前
- 住所: 北海道札幌市
- 連絡を取る:
Re: DrawFormatStringToHandle関数を拡張(?)したい
申し訳ございませんが、お二方の提示された解説サイトを拝見させていただきましたが、
正直なところ意味が理解できておりません。
どなたか解説を下さらないでしょうか(汗)
va_listはcharのポインタをtypedefで宣言している、というところまではわかっております。
va_start、va_endはファイル入出力でいうオープン・クローズ操作のようなものだと考えております。
まずそこは間違えてはいないでしょうか?
そして先に述べたマクロva_start、va_endはそれぞれ#defineで定義してあるだけのような気がしていて、
それが関数のように扱われていることがまず理解できません。
va_startの第1引数のva_list型ポインタに何らかの文字列が入ることは予想しております。
ですが、第2引数の*Stringだけを渡すのでは、これは意味がないのではないでしょうか。
正直なところ意味が理解できておりません。
どなたか解説を下さらないでしょうか(汗)
va_listはcharのポインタをtypedefで宣言している、というところまではわかっております。
va_start、va_endはファイル入出力でいうオープン・クローズ操作のようなものだと考えております。
まずそこは間違えてはいないでしょうか?
そして先に述べたマクロva_start、va_endはそれぞれ#defineで定義してあるだけのような気がしていて、
それが関数のように扱われていることがまず理解できません。
va_startの第1引数のva_list型ポインタに何らかの文字列が入ることは予想しております。
ですが、第2引数の*Stringだけを渡すのでは、これは意味がないのではないでしょうか。
オフトピック
初めて見る構文ばかりで、正直なところ混乱しておりますので、
日本語的におかしかったり、滅茶苦茶なことを発言してしまっている可能性がありますが、ご了承ください
日本語的におかしかったり、滅茶苦茶なことを発言してしまっている可能性がありますが、ご了承ください
ほら、来いよ!! 誤字や矛盾を指摘したい奴から、前に出てこいよぉおおおおおおおッ!!!
※都合により、不定期でしか現れません。即返などはできませんのでご了承ください※
※都合により、不定期でしか現れません。即返などはできませんのでご了承ください※
Re: DrawFormatStringToHandle関数を拡張(?)したい
分かりやすそうなサイトがありましたので、
http://wisdom.sakura.ne.jp/programming/c/c62.html
からva_start と va_end の解説を引用します。
こういうことをしているだけでは?
http://wisdom.sakura.ne.jp/programming/c/c62.html
からva_start と va_end の解説を引用します。
WisdomSoft(旧) さんが書きました: void va_start(va_list リスト , prev);
リストには、引数リストへのポインタを指定します
これは、可変個の引数の情報を保持するための stdarg.h で定義されている標準型です
pervは、最初の可変個数の手前の固定引数を指定します(最後の固定引数)
この時点で va_list 型の変数に、可変引数の情報が格納されます
次に、この va_list 型変数から、順に可変引数の内容を呼び出します
引数リストの値を得るにはva_arg()を使用します
void va_start( va_list arg_ptr, prev_param );
引数リスト arg_ptr の先頭をセットします
ヘッダ - stdarg.h
arg_ptr - 引数リストへのポインタを指定します
prev_param - 最初のオプション引数の直前の引数
最後に、すべての引数を取得したらva_end()でポインタを NULL にリセットします
void va_end(va_list リスト);
リストは、これまでva_start()やva_arg()で引数にアクセスしていた変数です
void va_end( va_list arg_ptr );
引数リストへのアクセスを終了し、ポインタをNULLにします
ヘッダ - stdarg.h
arg_ptr - 引数リストへのポインタを指定します
実行結果→http://ideone.com/GJOqkIamehirune さんが書きました:そして先に述べたマクロva_start、va_endはそれぞれ#defineで定義してあるだけのような気がしていて、
それが関数のように扱われていることがまず理解できません。
こういうことをしているだけでは?
初心者です
Re: DrawFormatStringToHandle関数を拡張(?)したい
>タイトルではDrawFormatStringToHandle関数というDXライブラリの関数を用いておりますが、
>実際に知りたいところはそこではなく書式付き文字列の表示の仕方なので、
だったら無意味なタイトルを付けなればいいのではないでしょうか.
本当の目的が一体何なのかが読み手にわかりにくくなるだけの効果しかないように思うのです.
結果として(私の読解力が低いだけかもしれませんけど),
vprintf() とか vsprintf() あたりに可変長の部分をうまいこと処理してもらえればそれでいいのか,
それとも
va_arg()を自分で使って一個ずつ引数をあれこれしたいのか
どちらなのかがはっきりと読み取れません.
可変長のとこの仕組みの説明はロベールがわかりやすいように思います.
http://www7b.biglobe.ne.jp/~robe/cpphtm ... 03016.html
>実際に知りたいところはそこではなく書式付き文字列の表示の仕方なので、
だったら無意味なタイトルを付けなればいいのではないでしょうか.
本当の目的が一体何なのかが読み手にわかりにくくなるだけの効果しかないように思うのです.
結果として(私の読解力が低いだけかもしれませんけど),
vprintf() とか vsprintf() あたりに可変長の部分をうまいこと処理してもらえればそれでいいのか,
それとも
va_arg()を自分で使って一個ずつ引数をあれこれしたいのか
どちらなのかがはっきりと読み取れません.
可変長のとこの仕組みの説明はロベールがわかりやすいように思います.
http://www7b.biglobe.ne.jp/~robe/cpphtm ... 03016.html
Re: DrawFormatStringToHandle関数を拡張(?)したい
ご回答ありがとうございます。
なので、理想としてはsprintf関数のように、すべての可変長引数の内容を文字配列に代入させ、
それをDrawFormatStringToHandleで表示させたいと考えているのです。
わかりにくくなってしまい、申し訳ありません。
vprintf関数といいますと、こちらが調べてみたところによると
printfとは引数の型が違うだけで動作内容としては全く変わらない…のではないかと思います。
DXライブラリではprintf関連の使用はできませんので、ソースコードに記述することができないのです。
なのでvsprintfこそが私の探していた関数だといえますね。
提示していただきありがとうございます。
私の環境では期待通りの実行結果が得られましたが、可変長引数についてわかるまで勉強するのがよさそうなので、
理解してから解決、とさせていただきたいです。
念のため、無事成功したソースコードのほうを載せさせていただきます。
ありがとうございます。早速勉強してみることにします。Rittai_3D さんが書きました:分かりやすそうなサイトがありましたので、
http://wisdom.sakura.ne.jp/programming/c/c62.html
いえ、最終的に実行させたいのはDrawFormatStringToHandle関数です。usao さんが書きました: だったら無意味なタイトルを付けなればいいのではないでしょうか.
本当の目的が一体何なのかが読み手にわかりにくくなるだけの効果しかないように思うのです.
結果として(私の読解力が低いだけかもしれませんけど),
vprintf() とか vsprintf() あたりに可変長の部分をうまいこと処理してもらえればそれでいいのか,
それとも
va_arg()を自分で使って一個ずつ引数をあれこれしたいのか
どちらなのかがはっきりと読み取れません.
なので、理想としてはsprintf関数のように、すべての可変長引数の内容を文字配列に代入させ、
それをDrawFormatStringToHandleで表示させたいと考えているのです。
わかりにくくなってしまい、申し訳ありません。
vprintf関数といいますと、こちらが調べてみたところによると
printfとは引数の型が違うだけで動作内容としては全く変わらない…のではないかと思います。
DXライブラリではprintf関連の使用はできませんので、ソースコードに記述することができないのです。
なのでvsprintfこそが私の探していた関数だといえますね。
提示していただきありがとうございます。
私の環境では期待通りの実行結果が得られましたが、可変長引数についてわかるまで勉強するのがよさそうなので、
理解してから解決、とさせていただきたいです。
念のため、無事成功したソースコードのほうを載せさせていただきます。
int DrawFormatStringToHandleEx(int x,int y,int Color,int FontHandle,const TCHAR *FormatString, ... ){
char Strings[256];
va_list list;
va_start( list,FormatString );
vsprintf( Strings,FormatString,list );
va_end( list );
DrawFormatStringToHandle( x,y,Color,font[FontHandle],Strings );
return 0;
}
オフトピック
こんな関数作る必要がないでしょ、と思う方もいらっしゃると思うので動機のほうを説明させていただきます。
仮想フルスクリーンモードを実装する際、どうしてもフルスクリーンモードかウィンドウモードかで使用するフォントが違ってきています。
なので、条件分岐を通して文字列を表示する必要があったわけなのですが、その処理をいちいち書いていれば非効率的だと思い、
関数化を図ろうとした次第です。
仮想フルスクリーンモードを実装する際、どうしてもフルスクリーンモードかウィンドウモードかで使用するフォントが違ってきています。
なので、条件分岐を通して文字列を表示する必要があったわけなのですが、その処理をいちいち書いていれば非効率的だと思い、
関数化を図ろうとした次第です。
ほら、来いよ!! 誤字や矛盾を指摘したい奴から、前に出てこいよぉおおおおおおおッ!!!
※都合により、不定期でしか現れません。即返などはできませんのでご了承ください※
※都合により、不定期でしか現れません。即返などはできませんのでご了承ください※
Re: DrawFormatStringToHandle関数を拡張(?)したい
オフトピック
DXライブラリのことはよくわかりませんが,最後に使うのは
DrawFormatStringToHandle()ではなく
DrawStringToHandle()で良いのではないでしょうか.
あと,vsprintf()はバッファオーバーランに注意が必要です.
https://msdn.microsoft.com/ja-jp/library/28d5ce15.aspx
のRemarksのとことか見ると良いかと思います.
DrawFormatStringToHandle()ではなく
DrawStringToHandle()で良いのではないでしょうか.
あと,vsprintf()はバッファオーバーランに注意が必要です.
https://msdn.microsoft.com/ja-jp/library/28d5ce15.aspx
のRemarksのとことか見ると良いかと思います.
Re: DrawFormatStringToHandle関数を拡張(?)したい
勉強したところ、ある程度分かった(ような気がする)ので、解決とさせていただきます。
皆様方、本当にありがとうございました
皆様方、本当にありがとうございました
ほら、来いよ!! 誤字や矛盾を指摘したい奴から、前に出てこいよぉおおおおおおおッ!!!
※都合により、不定期でしか現れません。即返などはできませんのでご了承ください※
※都合により、不定期でしか現れません。即返などはできませんのでご了承ください※