Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 在printf语句中使用*_C - Fatal编程技术网

C 在printf语句中使用*

C 在printf语句中使用*,c,C,有人能给我解释一下这些输出背后的逻辑吗?我想这里*被用作抑制字符,但我无法理解输出 main() { char *s="hello world"; int i=7; printf("%.*%s",s); } 输出:%s 如果您将printf语句替换为printf(“%,*%s”,s),那么您的输出将是,*hello world???这里您的格式化字符串被解释为两部分“%.*%”和“s”,其中前者是具有指定最大宽度的“转义”百分号(这就是您的*所做的)指针s的值。首先尝试删除第二个百分号 对不起

有人能给我解释一下这些输出背后的逻辑吗?我想这里
*
被用作抑制字符,但我无法理解输出

main()
{
char *s="hello world";
int i=7;
printf("%.*%s",s);
}
输出:%s


如果您将printf语句替换为
printf(“%,*%s”,s)
,那么您的输出将是,*hello world???

这里您的格式化字符串被解释为两部分
“%.*%”和
“s”
,其中前者是具有指定最大宽度的“转义”百分号(这就是您的
*
所做的)指针
s
的值。首先尝试删除第二个百分号

对不起,我想我应该先帮你试试这个,但现在对我来说很不方便

编辑:

是的,为了得到你想要的,你应该这样写:

// here width is a customized value you pass to specify the maximum width of string 
printf("%.*s", width, s); 

// and this would give "hello worl" as its output. notice the missing "d"
printf("%.*s", 10, s); 
再次编辑:

Plz检查

宽度:
字段的宽度在此处用十进制值指定。如果该值不够大,无法填充宽度,则字段的其余部分将填充空格(除非指定了0标志)。如果该值超出字段宽度,则该字段将展开以适合该值。如果使用*代替宽度说明符,则下一个参数(必须是int类型)指定字段的宽度。注意:将*与宽度和/或精度说明符一起使用时,首先是宽度参数,然后是精度参数,然后是要转换的值

再次编辑:

@卡兹的标准是正确的。见ISO-IEC-9899_1990(第2版第137页):

%匹配单个%:不进行转换或赋值。完全转化 规格应为%%


因此,在2%符号之间插入任何其他转换说明符将导致未定义的行为。

printf格式字符串
“%.*s”
无效。
*
字符不被视为转换抑制说明符,而是被视为指定精度的
字符的参数

与以下内容进行比较:

printf("%.*s", 3, str);
其中,
*
将下一个参数(3)作为精度字段(对字符串具有特定含义),然后,
s
将获取字符串。由于
3
是一个常量,这相当于将其硬编码为格式字符串:

printf("%.3s", str);
因此,这里有一个
%.*
,它看起来像是一个具有可变精度字段的转换的开始。它将使用
s
参数并将其视为
int
,这是未定义的行为

即使下一个参数实际上是一个int,接下来发生的事情是
*
变量精度后面的
%
字符不是有效的转换说明符。或者,它是一个有效的转换说明符,作为
%%
转换的一部分。但是用于编码文字
%%
%%
序列不支持两个字符之间的可选材料。ISO 9899:1999(关于
%%
说明符)规定,“完整的转换规范应为
%%


它还表示“如果转换规范无效,则行为未定义。”如果在
%%
规范之间包含宽度或精度字段等内容,则该规范无效,因为它违反了明确规定的要求,即“完整的转换规范应为
%%

为了回答您的具体问题,您的第一个
printf()
语句格式不正确,因为它没有为
*
修饰符提供int参数,并且未定义对
%
转换说明符的精度使用。在您的例子中,您的C实现似乎忽略了精度,因此您的print语句等价于:
printf(“%%s”,s),这将导致输出:

%s
hello w
%%
转换为输出中的
%%

对于第二个
printf()
语句,它的格式同样错误,因为您提供了无效的转换说明符,即
。使用此说明符的行为会导致未定义的行为。系统似乎输出了错误的说明符,然后输出
*
,然后处理输出字符串的
%s

,*hello world

printf()
中,转换说明符的
*
修饰符是一种从参数向
printf()
调用提供字段宽度或精度(或两者)的方法(而不是直接将硬编码数字输入格式字符串本身)。因此:

将打印输出:

%s
hello w

本例中的
*
是精度,因为它紧跟在小数点之后。对于字符串,这意味着将打印字符串中的最大字符数。

您的问题是
scanf
,但您的代码是
printf
。是哪一个?很抱歉,我写错了scanf,它将是printf。我已经编辑了它。但是我不认为像
“%.*%s”
这样的格式字符串是无效的,它不是人们通常想要的,但它与ANSI C标准完全兼容。很抱歉,我现在找不到这是在哪个部分指定的。我的ISO9899:1999副本说“如果转换规范无效,则行为未定义”。摸索格式字符串的后果是严重的。:)是的,你说得对,请检查我的最新答案黛雅,终于拿到了。谢谢