有一个函数,是我们从学习c语言就开始的第一天就接触的,那就是printf函数,可是这个家族的函数,带给我们的便利却不是一点半点,所以写一篇用法总结。
1.printf函数
格式化输出,可以输出八进制,十进制,十六进制,可以输出字符串,%p输出地址。基本的东西就不在赘述了。
printf是有返回值的,只是一般我们用不到。printf()函数也有一个返回值,它返回所打印的字符的数目。如果有输出错误,那么printf()会返回一个负数(printf( ) 的一些老版本会有不同的返回值)。
*号符,在printf函数中有着很强的格式化作用,如同linux中一样,* 代表任意匹配。
再看一个格式化输出十六进制的例子:
#include <stdio.h> #include <stdlib.h> #include <stdint.h> #include <string.h> int main(void) { unsigned int a=0x1; printf("%#010x",a); return 0; }
在编程中经常会打印地址,而一般要求打印8个字节,而字节前导我们不希望使用空格而是使用前导0来填充,就可以使用上面的写法。
# 号:使用格式说明的可选形式,#o 打印的则以0(零)开始,八进制,#x或者#X,则以0x或者0X开始,十六进制。
0(零):对于所有数字格式,用前导零填充而不是空格。如果出现 - 标志或者指定了精度(对于整数)则忽略该标志。
那么%#010x:就表示:以十六进制输出,输出长度一共为10,前导用0填充而不是空格。由于#x的作用占用了两个位置,因为要输出0x,所以还剩下8个位置,这样就指定输出了十六进制8个字节长度的数据。
如果这样觉得不好阅读,可以不使用#,直接手动书写0x前缀,指定宽度为8,前导0即可:如:
这是printf函数的常用方法,但是正真重要的,还是在于可变参数及其家族的变种函数。
2.fprintf函数
专注于文件操作的file printf。文件输出,其实是往文件中写内容,如同printf函数一样,虽然说它是输出函数,但实质上往输出流写数据。fprintf聚集了printf家族的传统,可以格式化写文件:
#include<stdio.h> #include<stdlib.h> int main(void) { float imag[10]; float j=0; FILE *fp; for(int i=0;i<10;i++,j=j+0.2) { imag[i]=1.0+j; } if((fp=fopen("test.txt","w+"))==NULL) { printf("err "); fflush(stdout); getchar(); exit(1); } fprintf(fp,"%s","imag[]={"); for(int i=0;i<10;i++) fprintf(fp," %.4f,",imag[i]); fprintf(fp,"%c",'}'); fclose(fp); return 0; }
输出文件:
fopen一个函数,使用w+的方式表示,打开一个文件,可以进行更新(读取和写入),如果该文件存在,就将其长度变为0,如果不存在则先创建之。
int fprintf( FILE *stream, const char * restrict format , ...);
按照format格式输出到stream。其实,在linux学习中,我们知道一切皆文件,这个FILE指针,是可以映射到标准输出的,即:printf(...)=fprintf(stdout,...).
3.sprintf
这个函数用得非常多,也非常重要,务必掌握。
作为printf家族成员,自然printf自带的格式化操作它都具有。sprintf主要用于把格式化输出写到指定字符数组中。
先看基础用法:
通过下面的例子了解sprintf的原理:
可以看到,sprintf把十进制数108放在字符数组buf中,但是存放的原理是,将十进制数的每一位变成字符存放在buf数组中,49对应ASCII字符1,48对应0,56对应8.这样之后,我们就可以预估计buf数组给多大空间合适。
sprintf可以很方便的格式化类型放在数组中,我们再看一个例子:
现在试想一个问题,我们经常编程的时候想要实现中文和英文的同时保存,但是,我们怎么以除了直接初始化的方式来执行英文和中文的链接呢?举例说明一下这个问题,我们想得到一个字符串,包含中文和英文,例如上面的hi,你好。我们可以这样初始化:char str[40]="hi,你好";但是,如果我们的中文,需要由其他地方给出呢?我们怎么做到拼接字符串?我们应该知道,中文所占字节一定是大于一个字节的,根据文本编码,对应2-4个字节(这个要注意哦)。比如现在给你两个字符串,一个是英文的,一个是中文的,你怎么把它拼接到一起?当然,库函数提供 了这样拼接功能的函数,可是,我们的sprintf也可以做到,而又因为sprintf支持各种格式,所以它使用是最频繁的,如上面例子呈现的那样。