小知识,大挑战!本文正在参与「程序员必备小知识」创作活动
本文已参与 「掘力星计划」 ,赢取创作大礼包,挑战创作激励金。
说起printf()函数,写代码的同学肯定都很熟悉,这是C语言中标准的打印函数,在调试代码或者信息输出的时候会经常用到。
其中printf函数的转换说明如下:
转换说明修饰符
printf()中的标记
下面就通过一个实际的例子来说明修饰符和标记的功能。
比如现在通过3个传感器采集外部设备电压值,并通过串口将采集的数据实时打印出来。打印相关代码如下:
printf( "\r\n ch max min rms ave \r\n" );
adc_all_value(0, &chAll_value);
printf("%d %d %d %d %d\r\n", 0, chAll_value.max, chAll_value.min, chAll_value.rms, chAll_value.ave);
printf("%d %f %f %f %f\r\n", 0, chAll_value.max * 3.3 / 4096, chAll_value.min * 3.3 / 4096, chAll_value.rms * 3.3 / 4096, chAll_value.ave * 3.3 / 4096);
adc_all_value( 1, &ch1_value );
printf( "%d %d %d %d %d\r\n", 1, ch1_value.max, ch1_value.min, ch1_value.rms, ch1_value.ave );
printf( "%d %f %f %f %f\r\n", 1, ch1_value.max * 3.3 / 4096, ch1_value.min * 3.3 / 4096, ch1_value.rms * 3.3 / 4096, ch1_value.ave * 3.3 / 4096 );
adc_all_value( 2, &ch2_value );
printf( "%d %d %d %d %d\r\n", 2, ch2_value.max, ch2_value.min, ch2_value.rms, ch2_value.ave );
printf( "%d %f %f %f %f\r\n", 2, ch2_value.max * 3.3 / 4096, ch2_value.min * 3.3 / 4096, ch2_value.rms * 3.3 / 4096, ch2_value.ave * 3.3 / 4096 );
通过串口输出的结果如下:
分别显示了采样通道的最大值,最小值,有效值,平均值。但是打印出来的数据格式看起来很费劲。希望在打印的时候,可以将数据按照每一列对齐。第一个想到的就是通过空格将这些数据隔开。 于是修改代码如下:
printf( "\r\n ch \t\tmax \t\t min \t\t rms \t\t ave \r\n" );
adc_all_value(0, &chAll_value);
printf("%d \t\t %d \t\t %d \t\t %d \t\t %d\r\n", 0, chAll_value.max, chAll_value.min, chAll_value.rms, chAll_value.ave);
printf("%d\t\t%f \t %f \t %f \t %f\r\n", 0, chAll_value.max * 3.3 / 4096, chAll_value.min * 3.3 / 4096, chAll_value.rms * 3.3 / 4096, chAll_value.ave * 3.3 / 4096);
adc_all_value( 1, &ch1_value );
printf( "%d \t\t %d \t\t %d \t\t %d \t\t %d\r\n", 1, ch1_value.max, ch1_value.min, ch1_value.rms, ch1_value.ave );
printf( "%d\t\t%f \t %f \t %f \t %f\r\n", 1, ch1_value.max * 3.3 / 4096, ch1_value.min * 3.3 / 4096, ch1_value.rms * 3.3 / 4096, ch1_value.ave * 3.3 / 4096 );
adc_all_value( 2, &ch2_value );
printf( "%d \t\t %d \t\t %d \t\t %d \t\t %d\r\n", 2, ch2_value.max, ch2_value.min, ch2_value.rms, ch2_value.ave );
printf( "%d\t\t%f \t %f \t %f \t %f\r\n", 2, ch2_value.max * 3.3 / 4096, ch2_value.min * 3.3 / 4096, ch2_value.rms * 3.3 / 4096, ch2_value.ave * 3.3 / 4096 );
在数据之间 添加 tab 制表符,这样输出的数据就会通过空格被隔开。
这样打印出来的数据看起来整齐了,但是在调试代码的时候,因为每次数据输出的长度不一样,要调试好多次,才能确定两列数据之间的空格有多少个,而且代码看起来也比较凌乱。 这时就可以使用printf函数的修饰符和标记来设置输出数据的格式。
代码修改如下:
char *s1="ch";
char *s2="max";
char *s3="min";
char *s4="rms";
char *s5="ave";
printf( "\r\n%4s %12s %12s %12s %12s\r\n",s1,s2,s3,s4,s5 );
adc_all_value(0, &chAll_value);
printf("%4d %12d %12d %12d %12d\r\n", 0, chAll_value.max, chAll_value.min, chAll_value.rms, chAll_value.ave);
printf("%4d %12.6f %12.6f %12.6f %12.6f\r\n", 0, chAll_value.max * 3.3 / 4096, chAll_value.min * 3.3 / 4096, chAll_value.rms * 3.3 / 4096, chAll_value.ave * 3.3 / 4096);
adc_all_value( 1, &ch1_value );
printf( "%4d %12d %12d %12d %12d\r\n", 1, ch1_value.max, ch1_value.min, ch1_value.rms, ch1_value.ave );
printf( "%4d %12.6f %12.6f %12.6f %12.6f\r\n", 1, ch1_value.max * 3.3 / 4096, ch1_value.min * 3.3 / 4096, ch1_value.rms * 3.3 / 4096, ch1_value.ave * 3.3 / 4096 );
adc_all_value( 2, &ch2_value );
printf( "%4d %12d %12d %12d %12d\r\n", 2, ch2_value.max, ch2_value.min, ch2_value.rms, ch2_value.ave );
printf( "%4d %12.6f %12.6f %12.6f %12.6f\r\n", 2, ch2_value.max * 3.3 / 4096, ch2_value.min * 3.3 / 4096, ch2_value.rms * 3.3 / 4096, ch2_value.ave * 3.3 / 4096 );
此时数据输出效果如下:
这时数据看起来就更加清晰明了了,数据默认采样了右对齐的方式。
这里主要使用的是数字修饰符
将每一列的名称转换成字符串,然后不直接输出字符串,而是使用打印字符的方式输出,这样就可以通过数字对输出的字符长度进行限制。比如字符串“ch”设置它占用的字符为4位,这样输出的时候,字符长度不够4位,就会用空格填充。然后将其他字符长度都设置为12位,空余的位置就会被空格填充,和直接打印空格效果一样。
对于整形数字来说,数字修饰符同样也是设置占用的位数长度,如果位数长度不够,就用空格代替。对于小数来说,小数点前面的数字表示小数整体占用的长度,小数点后面的数字代表小数位保留几位。比如“ %12.6f”代表浮点数整体占12位,小数部分保留6位。也就是说,整数部分占6位,小数部分也占6位。
打印的字符默认都是右对齐的,如果想要左对齐,直接在%后面加上“-”号就行了。这里将打印数据修改为左对齐,同时小数位保留2位。
修改代码如下:
char *s1="ch";
char *s2="max";
char *s3="min";
char *s4="rms";
char *s5="ave";
printf( "\r\n%-4s %-12s %-12s %-12s %-12s\r\n",s1,s2,s3,s4,s5 );
adc_all_value(0, &chAll_value);
printf("%-4d %-12d %-12d %-12d %-12d\r\n", 0, chAll_value.max, chAll_value.min, chAll_value.rms, chAll_value.ave);
printf("%-4d %-12.2f %-12.2f %-12.2f %-12.2f\r\n", 0, chAll_value.max * 3.3 / 4096, chAll_value.min * 3.3 / 4096, chAll_value.rms * 3.3 / 4096, chAll_value.ave * 3.3 / 4096);
adc_all_value( 1, &ch1_value );
printf( "%-4d %-12d %-12d %-12d %-12d\r\n", 1, ch1_value.max, ch1_value.min, ch1_value.rms, ch1_value.ave );
printf( "%-4d %-12.2f %-12.2f %-12.2f %-12.2f\r\n", 1, ch1_value.max * 3.3 / 4096, ch1_value.min * 3.3 / 4096, ch1_value.rms * 3.3 / 4096, ch1_value.ave * 3.3 / 4096 );
adc_all_value( 2, &ch2_value );
printf( "%-4d %-12d %-12d %-12d %-12d\r\n", 2, ch2_value.max, ch2_value.min, ch2_value.rms, ch2_value.ave );
printf( "%-4d %-12.2f %-12.2f %-12.2f %-12.2f\r\n", 2, ch2_value.max * 3.3 / 4096, ch2_value.min * 3.3 / 4096, ch2_value.rms * 3.3 / 4096, ch2_value.ave * 3.3 / 4096 );
打印结果如下:
可以看出,调整后的格式看起来更加清晰明了了。
通过使用printf的修饰符和标记,是程序看起来更简洁了,同时输出的格式也更美观了。