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副本说“如果转换规范无效,则行为未定义”。摸索格式字符串的后果是严重的。:)是的,你说得对,请检查我的最新答案黛雅,终于拿到了。谢谢