vlambda博客
学习文章列表

C语言输出格式控制语法(完整)

「今天是学习C语言第 28 天」


当你选择了一种语言,意味着你还选择了一组技术、一个社区。——Joshua Bloch

# 格式控制字符串

格式控制字符串是C语言输入输出函数中用来控制输入输出格式的参数,它是由百分号 % 语法表示的格式占位符组成的字符串表示。


输入输出函数,会将格式控制字符串中的 % 占位符换成参数列表中一一对应的变量值进行输入输出。

注:%% 可以输出百分号。


# 输出格式控制的基本语法

[]表示的字段可选,最基础的格式控制字符串是 %转换类型 。

注:输出格式控制中出现的普通字符序列会直接原状输出,只对%引导的转换说明符进行转换。

语法:

%[标志][最小域宽][.精度][类型长度字母]转换类型


1.标志

标志字符包括- + 空格 # 0 五种,意义如下:

-       

减号,表示在域宽范围内输出左对齐,默认输出是右对齐

例如:

printf("%-d\n",10);

printf("%-d\n",1000);

输出:域宽为1,超出域宽,默认从左到右输出,无对齐。

10

1000


printf("%-5d\n",10);

printf("%-5d\n",1000);

输出:域宽内左对齐,填充空格。

10

1000


printf("%5d\n",10);

printf("%5d\n",1000);

输出:域宽内右对齐,填充空格。

   10

 1000


+       

加号,有符号数转换输出带正号或负号,如果省略,默认只有负值带负号输出。

例如

printf("%d",10);   // 输出 10

printf("%+d",10);  // 输出 +10

printf("%+d",-10); // 输出 -10

printf("%d",-10);  // 输出 -10


空格    

有符号数输出时第一个字符不是符号或转换的结果没有字符时,自动在前面输出一个空格间隔,当空格和+同时出现,空格标志被忽略。

例如:

printf("%   d\n", 1000);   //  1000,1000前面加上一个空格

printf("%  +d\n", 1000);   // +1000,无空格,

printf("%   d\n", -1000);  // -1000,无空格,第一个字符是符号

printf("%   X\n", 1000) ;  // 3E8,输出有字符,忽略空格


结果被转换成替代形式

八进制o类型转换:增加精度,保证第一位数字是0

十六进制x或X类型转换:非零结果输出0x或0X前缀表示的十六进制

对e E f g G转换:结果始终包含十进制小数点字符,即使后面没有数字,仍然出现小数点

对g和G转换,结果保留结尾的零

printf("%d\n", 1000);   // 1000

printf("%#d\n", 1000);  // 1000


printf("%o\n", 1000);   // 1750

printf("%#o\n", 1000);  // 01750


printf("%x\n", 1000);   // 3e8

printf("%#x\n", 1000);  // 0x3e8


// 小数记数法,直接十进制表示,精度默认6

printf("%f\n",1000.0012);   // 1000.001200 

printf("%#f\n",1000.0012);  // 1000.001200 


printf("%.0f\n", 1000.0);          // 1000

printf("%#.0f\n", 1000.0);         // 1000.

printf("%.0f\n", 0);            // 0

printf("%#.0f\n", 0);           // 0.


// 科学记数法,指数表示,小数点后字符数为精度,默认是6

printf("%e\n", 1000.0012);   // 1.000001e+003 

printf("%#e\n", 1000.0012);  // 1.000001e+003 

printf("%.0e\n", 1000.0012); // 1e+003

printf("%#.0e\n", 1000.0012);// 1.e+003


// %g 自动选择记数法

printf("%g\n",1000.0012);    // 1000 

printf("%#g\n",1000.0012);   // 1000.00

printf("%#0.1g\n",1000.0012); // 1.e+003


0

- 对于d i o u x X e E f g G类型转换,使用0填充域宽;

- 默认是用空格填充;

- 0和-同时出现,忽略标志0;

- 对d i o u x X类型转换,规定精度字段时,忽略标志0。

例如:

    printf("%5d\n", 10);    //    10

    printf("%05d\n", 10);   // 00010

    printf("%-05d\n", 10);  // 10

    printf("%05.2d\n", 10); //    10


2.最小域宽

最小域宽取值是十进制整数或星号*。

- 转换后的输出值字符数比域宽少,右对齐时则在域宽的左边填充默认的空格字符;

- 左对齐时则在域宽的右边填充空格;

- 如果填充字符修改为0,则填充0;

- 若输出值的字符数比域宽多,则按实际位数输出;

- 星号*表示由输出函数的参数提供具体的域宽,该参数应紧跟格式控制参数之后出现;

- 负值域宽按照左对齐标记-和一个正的域宽对待。


例如:以下输出使用 ---表示三个空格。

    printf("%5d\n",10);  // ---10

    printf("%-5d\n",10); // 10---

    printf("%05d\n",10); // 00010

    printf("%5d\n", 100000); // 100000

    printf("%*d\n",5,10); // ---10


3.精度

精度取值形式是圆点.加上*或任意的十进制整数。

- 整数d i o u x X转换后的输出,精度表示输出最少数字字符数。

- 小数e E f 转换后的输出,精度表示在十进制小数点后应保留的最少数字字符数。

- 对g和G转换,表示最大有效数字字符数。

- 对于S转换表示一个字符串输出的最大字符数。

- 取值仅有圆点.时,精度默认是0。

- 取值为星号*,表示由输出函数的参数提供具体的精度,该参数应紧跟格式控制参数之后出现。负精度按照默认精度对待。

例如:

    printf("%.5d\n",10);  // 00010

    printf("%-.5d\n",10); // 00010

    printf("%0.5d\n",10); // 00010

    printf("%.5d\n", 100000); // 100000


    printf("%.*d\n",5,10); // 00010

    printf("%.*d\n", 10,2);  // 输出0000000002


    printf("%.2f\n",1000.0012);   // 1000.00

    printf("%.5f\n",1000.0012);   // 1000.00120


    printf("%.2g\n",1000.0012);   // 1e+003

    printf("%.5g\n",1000.0012);   // 1000

    

    printf("%.2s\n", "Hello");  // He

    printf("%.6s\n", "Hello");  // Hello

    printf("%.0s\n", "Hello");  // 不输出任何字符

    

4.类型长度

对于整数d,i,o,u,x,X转换,l表示long int 或unsigned long int类型参数,h表示short int 或 unsigned short int。

对于e E f g G转换,L表示long double类型参数。

例如

    // dev-c++ 编译32位平台编译(不同机器不同编译不同)

    printf("%d\n", sizeof(int));   // 4个字节

    printf("%d\n", sizeof(long int));   // 4个字节

    printf("%d\n", sizeof(unsigned long int));   // 4个字节

    printf("%d\n", sizeof(short int));   // 2个字节

    printf("%d\n", sizeof(unsigned short int));   // 2个字节

    printf("%d\n", sizeof(float));   // 4个字节

    printf("%d\n", sizeof(double));   // 8个字节

    printf("%d\n", sizeof(long double));   // 12个字节(dev-c++编译)


    // dev-c++ 编译64位平台编译

    printf("%d\n", sizeof(int));   // 4个字节

    printf("%d\n", sizeof(long int));   // 4个字节

    printf("%d\n", sizeof(unsigned long int));   // 4个字节

    printf("%d\n", sizeof(short int));   // 2个字节

    printf("%d\n", sizeof(unsigned short int));   // 2个字节

    printf("%d\n", sizeof(float));   // 4个字节

    printf("%d\n", sizeof(double));   // 8个字节

    printf("%d\n", sizeof(long double));   // 16个字节(GCC编译)

    

    printf("%d\n", 0xFFFF);   // 65535

    printf("%hd\n", 0xFFFF);  // -1

    printf("%hu\n", 0xFFFF); // 65535

    

    printf("%d\n", 0xFFFFFFFF);  // -1

    printf("%ld\n",0xFFFFFFFF);  // -1

    printf("%u\n", 0xFFFFFFFF);  // 4294967295

    printf("%lu\n", 0xFFFFFFFF); // 4294967295


5.转换类型

一个字符表示输出值转换类型,该字段是格式控制串中必须的字段。


d,i  

表示int整型转换为[-]dddd的有符号十进制数。精度规定输出的最少数字字符数,如果转换的值位数少于精度,使用0扩展,默认精度是1,零精度转换零值时结果是无字符。

例如:

printf("%d\n", 100);    // 100

printf("%d\n", -100);   // -100

printf("%i\n", 100);    // 100

printf("%i\n", -100);   // -100

// 默认精度为1 

printf("%.1d\n", 100);  // 100

printf("%.1d\n", -100); // -100

// 100的位数小于精度4,补0

printf("%.4d\n", 100);  // 0100

printf("%.4d\n", -100); // -0100

// 精度为0,100值位数大于精度,直接输出

printf("%.0d\n", 100);  // 100

printf("%0.1d\n",0);    // 0

printf("%.0d\n", 0);    // 不输出任何数字字符


o,u,x,X 

表示unsigned int整型转换成dddd的无符号八进制、无符号十六进制表示。默认精度1,使用0填充。

例如:

printf("%o\n", 100);    // 144

printf("%u\n", 100);    // 100

printf("%x\n", 100);    // 64

printf("%X\n", 100);    // 64

// 精度为4 

printf("%.4o\n", 100);  // 0144

printf("%.4u\n", 100);  // 0100

printf("%.4x\n", 100);  // 0064

printf("%.4X\n", 100);  // 0064

// 精度为0 

printf("%.0o\n", 100);  // 144

printf("%.0u\n", 100);  // 100

printf("%.0x\n", 100);  // 64

printf("%.0X\n", 100);  // 64


f

表示double类型转换为[-]ddd.ddd的十进制小数记法,默认精度是6,精度是指转换后值得小数点后保留的数字字符数。

例如:

printf("%f\n", 1000.0012);      // 1000.001200

printf("%f\n", -1000.0012);     // -1000.001200

printf("%f\n", 0.10000012);     // 0.100000

printf("%f\n", -0.10000012);    // -0.100000

printf("%.8f\n", 0.10000012);   // 0.10000012


printf("%f\n", 1000.0);         // 1000.000000

printf("%f\n", 1000.00);        // 1000.000000

printf("%f\n", 100);            // 1000.000000

printf("%#.0f\n", 1000.0);         // 1000.

printf("%.0f\n", 1000.0);          // 1000

printf("%#.0f\n", 0);           // 0.

printf("%.0f\n", 0);            // 0


e,E

表示double类型转换成[-]d.ddde[+/-]dd的指数形式,科学记法。

小数点前的一位数字不为0,除非当需要转换的参数值为0时。

精度是指十进制小数点后的数字字符数,默认是6。

例如:

printf("%e\n", 1000.0012);  // 1.000001e+003

printf("%e\n", -1000.0012); // -1.000001e+003

printf("%e\n", 0.10000012); // 1.000001e-001

printf("%e\n", -0.10000012);// -1.000001e-001

printf("%.8e\n", 0.10000012);// 1.00000120e-001

printf("%e\n", 1000.0);     // 1.000000e+003

printf("%e\n", 1000.00);    // 1.000000e+003

printf("%e\n", 100);        // 1.000000e+003

printf("%#.0e\n", 1000.0);  // 1.e+003

printf("%.0e\n", 1000.0);   // 1e+003

printf("%e\n", 0);          // 未定义

printf("%#.0e\n", 0);       // 未定义

printf("%.0e\n", 0);        // 未定义


g,G

表示double类型转换为f或e格式,G表示转换为E格式。根据输出宽度大小,自动选择使用%f或%e格式记数。

当转换结果的指数部分小于-4或大于等于精度,使用%e表示,否则选择%f表示。

输出时小数末尾的0被移除,如果小数点后没有数字,省略小数点。

精度规定有效数的数字位数(不包括小数点),精度为0时,则强制取精度1,默认精度6。

例如:

printf("%f\n",1000.0012);   // 1000.001200

printf("%e\n",1000.0012);   // 1.000001e+003

printf("%g\n",1000.0012);   // 1000

printf("%f\n",1000.012);    // 1000.012000

printf("%e\n",1000.012);    // 1.000012e+003

printf("%g\n",1000.012);    // 1000.01


printf("%f\n",1000000.012); // 1000000.012

printf("%e\n",1000000.012); // 1.000000E+006

printf("%g\n",1000000.012); // 1e+006

printf("%.0g\n",1000000.012); // 1e+006


c

int型转换为unsigned char类型。

例如:

    printf("%c\n", 'A'); // A

    printf("%c\n", 65 ); // A

    printf("%c", '\n');  // 转义字符换行


s

函数参数为字符串常量或字符数组指针,输出字符串,如果有精度,则最多输出精度规定的字符数。

若未规定精度,或精度大于数组长度,字符数组中必须有空字符'\0'。

例如:

    char str[] = "Hello";

    printf("%s\n", str);    // Hello

    printf("%s\n", "Hello"); // Hello


    printf("%.2s\n", str);   // He

    printf("%.2s\n", "Hello"); // He


p

例如:

    int i = 100;

    int *p = NULL;

    p = &i;

    printf("%p\n", p);  // 0062FE94


    void *v = p;

    printf("%p\n", v);  // 0062FE94


n

%n是很特别的格式控制,它不对参数进行转换,它将截止目前已输出的字符数量存储到对应的参数中。

需要提供int *指针参数。

例如:

#include <stdio.h>int main(void){int i;printf("hello world%n!!!\n", &i);printf("i=%d\n", i);return 0;}
输出结果: hello world!!! i=11

结果分析:

    %n不输出任何参数,%n之前已经输出 hello world 11个字符,写入变量i。

注:该类型编译器相关,vc编译器中需要开启 _set_printf_count_output( 1 ); 。Dev-C++不支持。


%

直接输出%字符,即使用 %% 输出百分号,不对参数转换。

例如:

    printf("%%\n");  // %


# 精度 vs 域宽

1.域宽过小时,不会截断参数的输出值,参数将按照实际值输出。

2.精度对每种类型的定义不一样,精度会截断输出值。

3.精度表示是以小数点 .ddd 表示。


---------- End ----------


往期精彩推荐:




「喜欢C请赏个 赞    点击右下角 在看」