printf中的“%。* s”是什么意思?


Answers:


119

您可以使用星号(*)将宽度说明符/精度传递给printf(),而不是将其硬编码为格式字符串,即

void f(const char *str, int str_len)
{
  printf("%.*s\n", str_len, str);
}

3
应该注意的是,str_len参数必须具有类型int(或更窄的整数类型,将被提升为int)。这将是传递一个错误longsize_t等等
MM

9
值得一提的是,此代码的可能目的(尤其是与一起使用时%s)是打印原始字符串的子字符串。在这种情况下,str将指向原始字符串内的某个位置(可能在开头),并str_len指定应打印的子字符串的长度。
Sonic Atom

2
通过指定长度,我们可以绕过打印(或sprintf)'没有空终止符的字符串,例如,从任何流或基于文件的源输入的字符串。我所遇到的用例远​​远超过了仅打印prettines。
康拉德B

23

这里更详细。

整数值或*指定最小字段宽度。如果需要,结果用空格字符填充(默认情况下),在右对齐时在左侧填充,在左对齐时在右侧填充。在使用*的情况下,宽度由类型为int的附加参数指定。如果参数的值为负,则结果将指定为-标志,且字段宽度为正。(注意:这是最小宽度:该值永远不会被截断。)

.后面跟整数或*,或者都不指定转换的精度。在使用*的情况下,精度由类型为int的附加参数指定。如果此参数的值为负,则将其忽略。如果既不使用数字也不使用*,则精度为零。有关精度的确切影响,请参见下表。

因此,如果我们尝试两种转换规范

#include <stdio.h>

int main() {
    int precision = 8;
    int biggerPrecision = 16;
    const char *greetings = "Hello world";

    printf("|%.8s|\n", greetings);
    printf("|%.*s|\n", precision , greetings);
    printf("|%16s|\n", greetings);
    printf("|%*s|\n", biggerPrecision , greetings);

    return 0;
}

我们得到输出:

|Hello wo|
|Hello wo|
|     Hello world|
|     Hello world|

12

我不认为上面的代码是正确的,但(根据这个描述printf())的.*手段

宽度不是在格式字符串中指定的,而是作为必须格式化的参数之前的附加整数值参数。

因此,这是一个字符串,其宽度作为参数可传递。


2
我添加了URL交叉引用,因此可以避免charges窃。当然,正确的引号是“ 精度不是……”而不是“ 宽度不是……”。
Jonathan Leffler

正如@MattMcNabb指出的那样,对该页面的每次引用都必须强调“ 整数值 ”是准确的int(或其一部分),而不仅仅是像更直观的整数值size_t或可能的别名(如)std::string::size_type。考虑到所引用的页面提到size_t的受支持的类型说明符之一,这甚至更加令人困惑。
安东·萨姆索诺夫

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.