Code::Blocks+wxSmithでprintf関数
津路です。
前回では、目標として、画面に図形やテキストを描いて、更に、図形をファイルに保存しました。
今回は、printfをまねた関数の実装を考えます。
1.新たにprintgという名前の関数を考える
2.出力先をTextCtrlにして、確かめるためのGUIを考える。
3.printfにて、デバッグする。
1.printgの引数には、先頭にformat用可変長文字列を、後続の引数リストには、可変個変数を与える。
1.1.va_listを定義して、引数を引き込む。
va_start,vsprintf,va_endを呼んで、format文字列に応じた引数値を取り込む。
文字列を入れるための内部バッファを定義する。
1.2.出力用のバッファを、別途クラス内に定義。サイズは、十分大きくしておく。
内部バッファに取り込んだ文字列と、出力用バッファの長さを足して、制限を超える分、出力してしまう。
1.3.出力用バッファに内部バッファを連結して、改行記号があれば、その分を出力
UTF8に変換して、wxTextCtrlにAppendTextする。
2.wxFrameベースのwxSmithプロジェクトを作成し、wxButtonとwxTextCtrlを配置する。
縦に配置するため、wxBoxSizerをまず配置して、OrientationプロパティをwxVERTICALにする。
すべてのwidgetを画面に見せるため、wxFrameのサイズを大きく設定しておく。
ボタンのClickイベントにて、出力する文字列の長さを変えてみる。
debugのためのcases
改行記号:ある、なし
長さ:制限を超える文字列、短い文字列
文字種:alphabet, number, symbol, etc.
3.printg関数内にて、printfを使って、メッセージを出力
konsole terminalにて、実行して、メッセージを参照する。
以下のようなコードになりました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | #define MAXPRINTOUT 500 char printout[MAXPRINTOUT]; void printg(const char *fmt, ...) { char buf[240]; va_list args; va_start(args,fmt); vsprintf(buf, fmt, args); va_end(args); short lenb, lenp; lenb = strlen(buf); lenp = strlen(printout); printf("lenb %d lenp:%d\n",lenb,lenp); if(lenb+lenp >= MAXPRINTOUT-2) { printf("lenb+lenp\n"); wxString wxP0(printout, wxConvUTF8); MainFrame->Results->AppendText(wxP0); printout[0] = '\0'; } strcat(printout, buf); lenp = strlen(printout); printf("lenp:%d\n",lenp); if(printout[lenp-1] == '\n') { printf("lenp terminated\n"); wxString wxP0(printout, wxConvUTF8); MainFrame->Results->AppendText(wxP0); printout[0] = '\0'; } } |
ただ、これでは、改行がないと、制限長さに至るまで出力されません。