格式字符串与多个百分号
我知道%%
用来逃避字符串中的实际%
迹象,所以%%%ds
最终会在以下格式字符串%10s
,但我不知道为什么我在这个字符串需要%%5s
?格式字符串与多个百分号
毕竟,只有两个附加参数(BUFFSIZE/10)。
#define BUFFSIZE 100
char buf[100]={0}
sprintf(buf, "%%5s %%%ds %%%ds", BUFFSIZE/10, BUFFSIZE/10);
运行上面的代码后,BUF将包含字符串,
%10s %10s
的目的是为了获得一个格式字符串中,需要一个格式字符串像sscanf()
另一个函数来使用它。
使用您的代码,您将得到:%5s %10s %10s
写入您的buf
,see online,这意味着它将接受三个具有长度标识符的字符串。
%%5s --> %5s
%%%ds with 10 --> %10s (read it that way: {%%}{%d}{s})
即缓冲器%5s %10s %10s
现在可以在一个sscanf()
呼叫可以使用像所示here。
但是,最好的做法是防止由sscanf()
引起的缓冲区溢出,Kernighan和Pike在其书The Practice of Programming中也描述了缓冲区溢出,请参见here on SO。
为什么你也许不能使用%*s
可能是这个原因,看here on SO:
为
printf
,则*允许您通过一个额外的参数指定最小字段宽度,即printf("%*d", 4, 100);
指定字段宽度为4.对于
scanf
,*表示该字段将被读取但被忽略,因此,即输入“12 34”的scanf("%*d %d", &i)
将忽略12并将其读入整数i。
%
本身是一个有效的转换说明符。在规定的语法,如在C11
,章§7.21.6.1/ P2,(重点煤矿)
每种转换规范由字符
%
引入提及。 的%
后,以下 出现在序列:
零个或更多个标志[...]
可选最小字段宽度。
可选的精度[...]
可选长度修改[...]
转换说明符字符,指定要应用的转换类型。
然后,P8,用于转换说明
转换标识符和它们的含义如下:
......
%
A
%
字符被写入。没有参数被转换。完整的 转换规范应为%%
。
因此,基于贪婪方法,编译器将组像
.... %%%ds, BUFFSIZE/10 ....
作为
{%%}{%d}{s}
^^--------------------------Replaced as %
^^----------------------Actual conversion specification happens, argument is used
^^------------------just part of final output
语法这最终产生
%Xs //where X is the value of (BUFFSIZE/10)
这是一个有效格式字符串(%
,最小字段宽度,转换说明符,全部按顺序),以后再使用。
你解释了一切,我的错误 –
@VishwajeetVishu Nevermind,没关系。同时我也在更新答案。 :) –
OP从参数大小计算格式字符串。给定的参数,该字符串将包含%5s %10s %10s
,其可与任一printf
或scanf
使用:
printf("%5s %10s %10s", "A", "B", "C");
输出:
A B C
char a[6], b[11], c[11];
scanf("%5s %10s %10s", a, b, c);
将读取3串入a
,b
,c
但限制了数为每个字符串读取字符以防止缓冲区溢出。
不过请注意,对于printf
情况下,没有必要计算字符串作为贴了,因为你也可以使用:
printf("%5s %*s %*s", "A", BUFFSIZE/10, "B", BUFFSIZE/10, "C");
不幸的是,scanf()
高度不同的语义为*
格式修改,这是无法指定要使用参数存储的最大字符数,只能使用格式字符串中的数字,因此需要单独的格式化步骤。
我在'buf'中获得'%5s%10s%10s',在这里演示http://ideone.com/c8MhN6。 _you_期望什么? –
这意味着某人要么过于聪明,要么不知道['%* s'](https://stackoverflow.com/questions/7105890/set-variable-text-column-width-in-printf)。 –
@ n.m。或者,不怕维护者(_Ref:暴力精神病患者) –