1 概论
C语言提供了跨平台的数据输入输出函数scanf()和printf()函数,它们可以按照指定的格式来解析常见的数据类型,例如整数,浮点数,字符和字符串等等。数据输入的来源可以是文件,控制台以及网络,而输出的终端可以是控制台,文件甚至是网页。
2 数据输出
从第一个C语言程序中,就使用了跨平台的库函数printf实现将一段文字输出到控制台,而实际上,printf()不仅可以将数据按照指定的格式输出到控制台,还可以是网页或者是指定的文件中,printf()函数执行的返回结果是输出字符的个数。
2.1 输出数据到网页
使用printf函数将数据按照指定的格式输出到网页的使用案例,目前我们公司内部的IT系统还有用C语言写的网页程序(cgi)。
#include <stdio.h>
/*
使用printf输出数据到网页
@author Tony [email protected]
@since 20160530 09:04
*/
void printf_html() {
//将生成的exe程序改成cgi就可以部署在Web服务器例如Apache中的cgi-bin目录中运行了就可以访问了。
//然后通过主机名+端口+文件名.cgi的方式访问
printf("Content-type:text/html \n\n");//声明输出的数据格式是HTML语言
printf("Hello World In HTML");
}
2.2 整数格式化输出
printf()函数的强大之处在于格式化显示输出整数,浮点数,字符以及字符串到文件,网页。同时在控制台我们可以使用这个函数来调试程序或者获取方法的返回值等等。
printf函数的表现形式为:printf(“格式化字符串数据”,可变参数列表)
printf只会按照传递的参数类型解析数据,不会进行数据类型转换,传入的参数类型和个数和输出的类型和个数保持一致,不然程序运行时会出异常
使用printf打印字符串,整数和字符的案例
#include <stdio.h>
/*
使用printf格式化输出数据
@author Tony [email protected]
@since 20160530 09:14
*/
void printf_sample() {
//最终都是以字符串的方式打印输出
printf("Hello World \n");//输出字符串常量,默认是输出到控制台
//printf显示不同数据类型的数据
printf("我的名字叫%s,我的年龄是%d我的幸运字符是%c\n","Tony",28,‘C‘);
}
printf在打印输出整数时,不仅可以按照三种不同的进制类型(八进制,十进制和十六进制),同时还可以按照有符号和无符号两种方式打印整数。
以及控制输出字符的宽度等等:
#include <stdio.h>
/*
输出指定格式的整数数据
如果要在网页下显示数据,还需要使用printf实现匹配不同的数据格式
@author Tony [email protected]
@since 20160530 09:20
*/
void printf_format_int() {
const int num = 10;
printf("%d",num);//默认的格式是有多宽 填充多宽
printf("%d\t%ld",num,num);//32位以上的系统%d和%ld是等效的 inth和long是等效的
printf("%10d\n",num);//宽度为10,数据显示默认是右边对齐
printf("%010d\n",num);//宽度为10,如果不足则用0来补充
printf("%-10d\n",num);//宽度为10,默认是按照右边对齐, "-"表示左边对齐
printf("%3d\n",12345); //12345大于实际宽度,3d的格式无效,不足使用空格填充
/*
输出指定格式的整数(有无符号类型以及三种进制类型的)数据
如果要在网页下显示数据,还需要匹配不同的格式
@author Tony [email protected]
@since 20160530 10:11
*/
void printf_format_int_data_type() {
const int num = 10;
printf("%d\n", num);//有符号十进制
printf("%i\n",num);
printf("%u\n",num); //无符号十进制
printf("%o\n",num);//无符号八进制
printf("%x\n",num); //无符号十六进制
}
/*
@author Tony [email protected]
@since 20160530 21:53
*/
void printf_format_int_unsinged() {
unsigned short int uvalue = 65535;
short int num = 123;
printf("uvalue =%hu\tnum=%hd",uvalue,num);
}
2.3 浮点数格式化输出
printf在打印输出浮点数时,整数全部输出,默认保持小数点后六位,可以按照小数和科学计数法(天文数字使用科学计数法存储节约内存)计数法两种方式,同时可以控制输出的小数位数和宽度:
#include <stdio.h>
/*
输出指定格式的浮点数数据
@author Tony [email protected]
@since 20160530 10:06
*/
void printf_format_double() {
const double num = 3.14159265359;
printf("num=%.2f\n", num);//小数点后保留两位
printf("num=%030.10f\n",num);//宽度为30,不足用0补齐,否则按实际宽度输出
//科学计数法表示
double depth = 1234567000000.0;
printf("depth=%e\n",depth);//指数表示
double value = 1.23456789;// %g 自动选择宽度少的显示数据 %f.%e
printf("value=%f\tvalue=%e\tvalue=%g",value,value,value);
}
2.4 格式化输出字符和字符串
printf在输出字符时通过%c格式符来输出,同时提供了putchar()函数来输出一个字符:
#include <stdio.h>
/*
格式化输出字符
@author Tony 186017672212163.com
@since 20160530 10:15
*/
void printf_char() {
char ch = ‘A‘;
printf("ch=%c\n",ch);
putchar(ch);
}
printf在输出字符串时,可以通过sprintf函数实现将字符串按照指定的格式拼接:
#include <stdio.h>
/*
输出指定格式的字符串数据
@author Tony [email protected]
@since 20160530 10:08
*/
void printf_format_string() {
char str[100] = "calc"; //输出字符串
printf("%s\n",str);
}
/*
使用sprintf函数实现字符串拼接
@author Tony [email protected]
@since 20160530 10:32
*/
void sprintf_string_append() {
char command[100] = { 0 };
sprintf(command, "color %c%c", ‘4‘, ‘f‘);//将整数 实数和字符串整合到一个字符串
printf("整合的结果为%s\n", command);
system(command);
system("pause");
char com[10] = "task";
char mand[10] = "listerror";
//command = com + mand; C语言没有Java语言中的字符串以加号的方式拼接
/*
%s%s表示字符串拼接
%.4s 从左边截取4位,只能从左边截取(从某一地址从左向右开始截取)
-左边对齐
*/
sprintf(command,"%s%.4s",com,mand);//
printf("%s\n",command);
system(command);
system("pause");
}
使用sprintf函数结合字符串指针实现身份证的出生日期信息获取
/*
通过sprintf截取身份证的出身年月日
@author Tony [email protected]
@since 20160601 14:29
*/
void sprintf_id() {
char id[19] = "421023198902345678"; //字符串是以\0结尾 因此要多出一个字符长度
printf("身份证号为%s",id);
char bornDate[9] = {0}; //初始化一个字符串保存出生日期
sprintf(bornDate,"%-.8s",id+6);//地址向后移动六位
printf("出身年月日为%s\n",bornDate);
}
2.5 printf格式化输出数据的参数总结
格式符 | 解析方式 |
---|---|
%hd | 有符号十进制短整数(short) |
%hu | 无符号十进制短整数(unsinged short) |
%d | 有符号十进制整数(int或者long) |
%lld | 有符号十进制整数(long long) |
%#o | 无符号八进制整数(#表明进制) |
%#x/%#X | 无符号十六进制整数(#表明进制,大小写决定了输出数据的字母大小写) |
%u | 无符号十进制整数 |
%llu | 无符号十进制整数(long long)用于存储身份证号 |
%c | 字符 |
%s | 字符串 |
%p | 指针地址 |
%f | 浮点数 |
%a | 十六进制浮点数 |
%e/%E | 指数形式的浮点数 |
%g | f和e相比宽度更小的浮点数 |
3 数据输入
scanf()函数主要是用于读取数据(通常来源于文件或者是用户从键盘的输入),并且按照指定的格式精确匹配(不能遗漏任何字符),绝大多解析数据的数据格式都和printf()一致。在扫描读取整数,浮点数和字符时通常变量名要加上地址符(&),在扫描读取字符串时变量名不需要加上地址符。scanf函数返回的是成功读取输入数据的个数
scanf()函数的一般形式是scanf(“格式字符串”,变量地址表)
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
/*
scanf读取用户从键盘的输入数据
@author Tony [email protected]
@since 20160601 16:59
*/
void scanf_sample() {
int num = 0;
printf("num变量的地址为:%p\n",&num); //打印变量的内存地址
scanf("num=%d",&num); //根据地址对应的变量值对变量进行初始化赋值 控制台中应该输入num=整数值(例如12)
printf("num=%d\n",num);
int x = 1, y = 2, z = 3;//声明多个整数
scanf("x=%d,y=%d,z=%d",&x,&y,&z);//命令行窗口应该输入x=整数值,y=整数值,z=整数值 格式字符串必须完全匹配
printf("x=%d,y=%d,z=%d",x,y,z);
system("pause");
}
在使用scanf函数进行读取数据的匹配时,如果数据类型是字符串,会忽略回车。
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
/*
scanf精确匹配
@author Tony [email protected]
@since 20160601 17:25
*/
void scanf_match() {
//当使用字符串(字符数组)时,输入回车会被忽略
int num=123;
char str[100] = { 0 };
scanf("%d", &num);//扫描读取num
scanf("%s",str);//扫描读取字符串
printf("num=%d\n",num);
printf("str=%s\n",str);
system("pause");
}
使用sscanf实现数据挖掘的案例:
一次性读取多个数据时可以使用回车键 空格或者是Tab实现数据读取结束符
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
/*
使用sscanf函数实现数据挖掘
@author Tony [email protected]
@since 201060601 17:34
*/
void scanf_match_data() {
char data[300] = "身高 170 年龄 22 体重 96 ";//空格表示读取结束
int height = 0;
int age = 0;
//使用sscanfh函数读取字符串到变量中,按照指定的格式匹配
sscanf(data, "%*s %d %*s %d %*s",&height,&age); //按照指定的格式进行数据解析,并读取到变量中
printf("height=%d\nage=%d\n",height,age);
height >= 170 && (age >= 20 && age <= 22)?printf("是女神标准\n"):printf("不是女神标准\n");
char info[300] = "QQ,1079351401,手机,18601767221,邮箱,[email protected]";
long long qq = 0;
long long mobilePhone = 0;
char email[30] = {0};
//先对字符串中的逗号,转换成空格 因为当sscanf函数进行字符串解析时,会将逗号后面的内容都当作字符串
for (int i = 0; i < 300;i++) {
if (info[i]==‘,‘) {
info[i] = ‘ ‘;
}
}
//%*s表示忽略该字符串的内容
sscanf(info,"%*s %lld %*s %lld %*s %s",&qq,&mobilePhone,email);
printf("qq=%lld\nmobilePhone=%lld\nemail=%s\n",qq,mobilePhone,email);
system("pause");
}
在使用scanf函数读取数据时,如果读取的是浮点数,则不能指定精度。
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
/*
scanf函数的使用注意事项
@author Tony [email protected]
@since 20160602 10:00
*/
void scanf_app() {
float fl = 0;
printf("请输入一个浮点数\n");
scanf("%7.2f",&fl);//scanf匹配浮点数时不能指定精度,此处将会解析数据错误
printf("fl=%f\n",fl);
system("pause");
}
在使用scanf读取字符数据时,回车,转义字符等都会当作一个有效的字符
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
/*
scanf函数的使用注意事项
@author Tony [email protected]
@since 20160602 10:00
*/
void scanf_app() {
char ch1=‘0‘;
char ch2 = ‘0‘;
scanf("%c,%c",&ch1,&ch2);
printf("ch1=[%c],ch2=[%c]",ch1,ch2);//回车符也会被当作输入的一个字符
system("pause");
}
使用scanf函数结合正则表达式扫描匹配指定正则的数据
/*
scanfh函数结合正则表达式的使用
@author Tony [email protected]
@since 20160604 20:43
*/
void scanf_regualr_express() {
//正则表达式就是一组验证数据的规则,常用在网页中的邮箱,密码等用户数据的验证
char str[200] = {0};
//scanf("%s",str);//默认是以回车中断读取数据
//scanf("%[^\n]",str);//处理空格 以回车作为结束读取
//scanf("%[^=]", str);//读取非=的数据 等号(=)作为结束读取(读取的结果不包含等号)
//scanf("%[^,]", str);//读取非(^)逗号的数据 逗号(,)作为结束读取(读取的结果不包含逗号)
//printf("%s\n",str);
//数字匹配(手机号) 0-9
//scanf("%[0-9]",str);//读取电话号码
//printf("%s\n", str);
//字母匹配a-zA-Z
scanf("%[a-zA-Z]", str);//读取字母,遇到非大小写字母结束,如果读取的字符串开头不匹配 输出为空
printf("%s\n", str);
//大写字母匹配A-Z
scanf("%[A-Z]", str);//读取字母,遇到非大写字母结束,如果读取的字符串开头不匹配 输出为空
printf("%s\n", str);
//小写字母匹配a-z
scanf("%[a-z]", str);//读取字母,遇到非小写字母结束,如果读取的字符串开头不匹配 输出为空
printf("%s\n", str);
}
欢迎扫描下方的二维码,关注微信公众服务号-艺无止境,分享IT技术干货。