指定されたウィンドウにメッセージを出力し、その属性を変更するmvwprint/mvwchgat ncurses関数のラッパー関数を書きたいと思います。
ただし、mvwchgatは変更すべき文字数を知る必要があります。たとえば、strlen() をオンにすると明らかに5 が返されるため、書式設定された文字列の長さをmvwchgatに伝える方法がわかりません。を意味する ..."abc%d"
%d
C99 または C11 では、次のような行を使用できます。
length = snprintf(NULL, 0, format_string, args);
(強調鉱山)のマニュアルsnprintf
から:
関数 snprintf() および vsnprintf() は size バイト (終端の null バイト ('\0') を含む) を超えて書き込みません。この制限のために出力が切り捨てられた場合、戻り値は、十分なスペースが利用可能であった場合に最終的な文字列に書き込まれた文字数 (終端の null バイトを除く) です。したがって、サイズ以上の戻り値は、出力が切り捨てられたことを意味します。
サイズとして 0 を指定しているためsnprintf
、出力は常に切り捨てられ、 の出力は、基本的に文字列の長さである、書き込まれた文字数になりsnprintf
ます。
C89 では、snprintf
. 回避策は、一時ファイルを作成することです。または、*nix open/dev/null
を使用している場合は、次のように記述します。
FILE *throw_away = fopen("/dev/null", "w"); /* On windows should be "NUL" but I haven't tested */
if (throw_away)
{
fprintf(throw_away, "<format goes here>%n", <args go here>, &length);
fclose(throw_away);
} /* else, try opening a temporary file */
文字列の長さを事前に知ることはできません。
printf("abc%d", 0); //4 chars
printf("abc%d", 111111111);//12 chars
すべて同じフォーマット文字列です。
唯一確実な方法はsprintf
、問題のテキストをバッファーに入れstrlen(buffer)
、結果とprintf("%s", buffer);
結果をスクリーニングすることです。
このソリューションは、十分な長さのバッファーを割り当てることを犠牲にして、二重のフォーマットを回避します。