int x;
printf("hello %n World\n", &x);
printf("%d\n", x);
8 に答える
にはあまり役に立ちませんが、特に複数の反復で文字列を解析している場合は、 printf()
非常に役立ちます。読み込まれた入力の量だけ内部ポインターを自動的に進めますが、そうではありません。例えば:sscanf()
fscanf()
scanf()
sscanf()
char stringToParse[256];
...
char *curPosInString = stringToParse; // start parsing at the beginning
int bytesRead;
while(needsParsing())
{
sscanf(curPosInString, "(format string)%n", ..., &bytesRead); // check the return value here
curPosInString += bytesRead; // Advance read pointer
...
}
悪事に 使え る。
実用的とは何を意味するかによって異なります。これを達成する方法は常に他にもあります (たとえば、s[n]printf を使用して文字列バッファーに出力し、長さを計算します)。
でも
int len;
char *thing = "label of unknown length";
char *value = "value value value"
char *value2="second line of value";
printf ("%s other stuff: %n", thing, &len);
printf ("%s\n%*s, value, len, value2);
生成する必要があります
label of unknown length other stuff: value value value
second line of value
(テストはしていませんが、私は C コンパイラの近くにはいません)
これは、物事を整列させる方法としてはほぼ実用的ですが、コードで見たくありません。それを行うより良い方法があります。
かなり難解です。後で生成された文字列のプレースホルダーを置き換える必要がある場合は、元の printf パラメーターを保存したり、文字列を解析したりする必要がないように、文字列の途中にインデックスを覚えておくことをお勧めします。
#include <stdio.h>
int main(int argc, char* argv[])
{
int col10 = (10 - 1);
int col25 = (25 - 1);
int pos1 = 0;
int pos2 = 0;
printf(" 5 10 15 20 25 30\n");
printf("%s%n%*s%n%*s\n", "fried",
&pos1, col10 - pos1, "green",
&pos2, col25 - pos2, "tomatos");
printf(" ^ ^ ^ ^ ^ ^\n");
printf("%d %d\n", pos1, pos2);
printf("%d %d\n", col10 - pos1, col25 - pos2);
return 0;
}
私は確かにここに何かが欠けています。トマトは右に行き過ぎています。
さまざまな部分文字列の長さを取得する簡単な方法として使用できる可能性があります。
あなたは電話することができます
int _get_printf_count_output();
%n サポートが有効かどうかを確認するか、
int _set_printf_count_output( int enable );
%n 形式のサポートを有効または無効にします。
MSDN VS2008 から
VS2005 CRT コードの一部を次に示します。
/* if %n is disabled, we skip an arg and print 'n' */
if ( !_get_printf_count_output() )
{
_VALIDATE_RETURN(("'n' format specifier disabled", 0), EINVAL, -1);
break;
}
これは次のようになります。
代替テキスト http://www.shiny.co.il/shooshx/printfn.png
次の行の場合:
printf ("%s other stuff: %n", thing, &len);
これは主に@eJamesが話していることを避けるためだと思います