printf()函数详细了解
最原始的数据输入输出是经过终端(黑窗口),后面随着计算机技术的发展,出现了图形界面(例如网页的表单)以及移动终端上常用的语音输入输出(IOS的Siri,Android的讯飞语音)的发展过程。
C语言提供了一系列的数据输入输出的函数,从第一个helloworld程序中使用的printf()函数以及后面用于读取键盘输入的scanf()函数以及字符的输入输出putchar(),getchar()等等。
printf()函数详解
printf本意是print format,也就是格式化输出,默认输出是到终端(控制台),同时结合重定向符号”>”可以输出到文本,如下应用所示
/* 使用printf函数结合重定向>输出数据到文本 @author tony ittimeline@163.com @date 2017/12/03 13:07 @website www.ittimeline.net */ void printf_text() { printf("输出数据到文本的案例"); printf("架构设计、人工智能"); }
当使用VisualStudio菜单的的生成->生成解决方案(Ctrl+Shift+B)后,在解决方案的Debug目录下(例如C:\Users\tony\source\repos\CPrimerPlus6\Debug)有一个编译好的二进制文件CPrimerPlus6.exe,如图所示
也可以将数据格式化显示在网页(1.6 helloworld详解章节中详细解释过如何输出在网页,这里不再赘述)。
printf()函数其特点是会按照指定的格式进行数据解析后输出,不会进行数据类型转换,如下所示,按照正确的数据格式解析会得到正确的结果。
#include/* printf函数按照指定的格式解析数据案例 @author tony ittimeline@163.com @date 2017/12/03 13:29 @website www.ittimeline.net */ void prinf_summary() { printf("hello printf\n"); //默认输出到控制台(命令提示符程序)输出的数据最终都是字符串 printf("num=%d\t str=%s\n",10,"timeless"); //输出到命令行终端、文件、网页 system("pause"); }
C语言没有提供Java那样通过加号连接字符串,但是可以使用sprintf()函数实现字符串的拼接,如下应用程序所示,根据用户输入的字符串(0-9,A-F),然后拼接成命令实现终端窗口的颜色变化,在终端上执行。
#define _CRT_SECURE_NO_WARNINGS #include#include /* sprintf函数用于字符串整合 @author tony ittimeline@163.com @date 2017/12/03 13:29 @website www.ittimeline.net */ void sprintf_sample() { printf("请输入一个字符串 用来变换终端的颜色\n"); char str[100] = { 0 }; char input[100] = { 0 };//存储输入的字符串 scanf("%s", input);//读取输入的字符串 //.2s 就是从左到右截取俩字符 sprintf(str, "color %.2s", input);//将输入的字符串(第二个参数)整合到str字符串中 system(str);//执行命令调用 system("pause"); }
printf通用格式控制字符的使用
在日常开发中,例如cgi网页程序中可能需要使用到调整数据的对齐方式,数据的指定的宽度以及数据的截取等等,这就会使用到一些通用的格式控制字符,如下的表格描述了具体的格式化字符串以及它们的作用。
格式符 | 功能描述 |
---|---|
- | 默认的数据输出是右对齐,这里使用左对齐的方式。 |
m | 控制数据的显示宽度,如果实际的宽度大于m,按照实际的宽度显示,如果实际的宽度小于m,则填充0或者空格 |
.n | 作用于浮点数,则是保留小数点后n位,如果是作用于字符,则是截取字符的长度。 |
0 | 输出的空位用0填充 |
l | 输出长整型整数 |
printf()函数通用数据格式控制字符应用案例如下所示
#include#include /* 通用的格式控制字符串详细说明 m 限定宽度,如果实际宽度多余m,按照实际的位数输出,如果少于m,则补零或者空格 .n 对于浮点数,小数点后保留n位 ,对于字符串,截取n位 l 输出长整数 o 输出的空位用0填充 - 输出的数字或者字符以左对齐(默认是右对齐) 右边填充空格 @author tony ittimeline@163.com @date 2017/12/28 10:29 @website www.ittimeline.net */ void print_format_info() { // int num = 10; printf("%d\n", num);//默认是右边对齐有多宽分配多宽 printf("%10d\n", num);//限定宽度为10 如果是实际位数多余10,按照实际位数输出,如果少于10位数,则补零或者空格 printf("%010d\n", num);//宽度为10,空余填充0 printf("%-d\n", num); //"-"左边对齐 //小数点后保留两位 printf("%.2f\n",3.1415927); //截取字符串 char str[100] = "notepad1"; char command[100] = {0}; sprintf(command,"%.7s",str); system(command); printf("%ld\n",123456789); //%d和%ld在32位以上的系统是等价的 system("pause"); }
字符串的截取案例
日常开发中的字符串截取除了最常使用的从左向右截取外,还有截取中间的指定部分内容,例如获取身份证的出生年月等等
截取身份证的出生年月日如下应用程序所示
#include#include /* 截取身份证的出生年月日 @author ittimeline@163.com @date 2018/1/1 20:56 @website www.ittimeline.net */ void spintf_split_id_brithday() { //身份证 char id_str[20] = "140211197605010352"; char brithday[10] = { 0 }; sprintf(brithday,"%.8s",id_str+6); printf("当前用户的生日是%s",brithday); system("pause"); }
#include#include /* 借助移动字符地址实现反向截取字符串 @author ittimeline@163.com @date 2018/1/1 20:56 @website www.ittimeline.net */ void sprintf_split() { //从左向右截取 char taskstr1[100] = "task"; char liststr1[100] = "list123"; char taskliststr1[100] = {0}; sprintf(taskliststr1,"%s%.4s",taskstr1,liststr1);//liststr从左向右截取四个长度的字符 printf("taskliststr1=%s",taskliststr1); system(taskliststr1); //从中间部分截取 char taskstr2[100] = "task"; char liststr2[100] = "123list123"; char taskliststr2[100] = { 0 }; sprintf(taskliststr2, "%s%.4s", taskstr2, liststr2+3);//liststr从左向右截取四个长度的字符,该字符地址向后移动3个字符(这样实现将左边的123字符丢弃) printf("taskliststr2=%s", taskliststr2); system(taskliststr2); system("pause"); }
在日常开发中,printf()最常用的使用场景就是解析各种数据类型,例如整数、浮点数、字符、字符串等等。
printf()函数解析整数时常用的格式如下
整数按进制分为八进制、十进制、十六进制,默认为十进制
十进制整数按照有无符号分为有符号整数和无符号整数
格式化字符串 | 解析方式 |
---|---|
%d/%i | 有符号十进制整数 |
%u | 无符号十进制整数 |
%o | 无符八进制整数 |
%x | 无符号十六进制整数 |
%lld | 有符号long long类型 |
printf解析整数的总结案例如下所示
#include#include /* printf解析整数总结 %d %i 有符号十进制 %u 无符号整数 %o 无符号八进制 %x 无符号十六进制 @author tony ittimeline@163.com @date 2018/1/1 15:32 @website www.ittimeline.net */ void printf_int() { int num = 100; //十进制整数才有有无符号的区分 printf("100的有符号十进制表示值为%d\n",100); //输出结果显示%d和%i显示效果一样 printf("100的有符号十进制表示值为%i\n", 100); printf("100的无符号十进制表示为%u\n",100); printf("100的无符号八进制表示值为%o\n", 100); printf("100的无符号十六进制表示值为%x\n", 100); //在32位数以上的机器上int和long是等价的,占据4个字节的内存大小。 //但是在16位的机器上,short和int是等价的,都是占据2个字节的大小 //因此区分机器的不同,在解析long类型的数据时推荐使用%ld来获取正确的解析结果 long lngVal = 12345678910; printf("lngVal = %d \t lngVal=%ld",lngVal,lngVal); system("pause"); }
printf()函数解析字符和字符串的格式如下所示
格式字符串 | 解析方式 |
---|---|
%c | 字符 |
%s | 字符串 |
printf()函数解析字符和字符串的应用案例如下所示
输出单个字符还可以使用putchar()函数实现
#include#include /* printf函数处理字符和字符串 %c 输出字符 %s 输出字符串 @author tony ittimeline@163.com @date 2018/1/1 20:12 @site www.ittimeline.net */ void printf_char_str() { char ch = 'A'; printf("ch变量存储的字符是%c\n",ch); //使用putchar()函数输出一个字符 putchar(ch); char cmd[100] = "notepad"; printf("%s",cmd); system("pause"); }
printf()函数解析浮点数的格式如下表格所示
格式字符串 | 解析方式 |
---|---|
%f | 浮点数 |
%e | 指数(科学计数法,一般都用来表示天文数字) |
%g | 选择%f和%e之间占据宽度最小的表示方式 |
printf()函数输出浮点数的应用案例
#include#include /* printf()函数输出浮点数数据 @author tony ittimeline@163.com @date 2018/1/1 21:30 @site www.ittimeline.net */ void printf_float_double() { double dblVal = 12.3456789; printf("数据12.3456789小数点后取4位数的结果为%.4f\n",dblVal); //日常开发中极大的数据和极小的数据通常都是用指数表示 double chinese_gdp = 80000000000000; printf("今年中国的GDP是%e\n",chinese_gdp); printf("****************华丽的分割线********************\n"); //%g 自动选择宽度比较小的数据格式存储(%f或者%e),可以节约内存 //double db = 1234567890000; double db = 1234.56789; //%f默认保留的小数点后六位, 输出结果时会进行四舍五入 printf("%f\n, %e\n, %g\n", db, db, db);//g自动选择宽度较短(%f|%e)的一个进行打印 system("pause"); }