scanf/sscanf/fscanf和printf/sprintf/fprintf详解

针对scanf/sscanf/fscanf和printf/sprintf/fprintf进行详细讲解,以及两组函数的对比


int scanf( const char* format [,argument]… );(一种格式化的输入函数)
解释:
format是C字符串(可以是一个变量),包含了以下各项中的一个或多个
其形式为:"%[*][width(宽度)][length(类型长度)][type]“

参数 作用说明
* 这是一个可选星号,表示数据是从流stream中读取的,但是可以被忽视,即它不存储在对应的参数中
width 指定了在当前读取操作中读取的最大字符数
length h :短整型或无符号短整型 l :长整型或无符号长整型或双精度型 L :长双精度型
type 一个字符,指定了要被读取的数据类型以及数据读取方式。具体参见下一个表格
占位符 输入说明 对应类型
%c 单个字符:读取下一个字符。如果指定了一个不为 1 的宽度 width,函数会读取 width 个字符,并通过参数传递,把它们存储在数组中连续位置。在末尾不会追加空字符。 char *
%d 十进制整数:数字前面的 + 或 - 号是可选的 int *
%e、%E、%f、%F、%g、%G 浮点数:包含了一个小数点、一个可选的前置符号 + 或 -、一个可选的后置字符 e 或 E,以及一个十进制数字。两个有效的实例 -732.103 和 7.12e4 float *
%i 读入十进制,八进制,十六进制整数:数字前面的 + 或 - 号是可选的 int *
%o 八进制整数:数字前面的 + 或 - 号是可选的 int *
%s 字符串。这将读取连续字符,直到遇到一个空格字符(空格字符可以是空白、换行和制表符)。 char *
%u 无符号的十进制整数。 unsigned int *
%x、%X 十六进制整数:数字前面的 + 或 - 号是可选的 int *
%p 读入一个指针 。
%[] 扫描字符集合 。
%*c 忽略一个输入字符。
%n 获取前一次输入的长度
%% 读 % 符号。

注意
1.占位符为%s
scanf在输入字符串时,虽然不会接收空白符(回车‘\n’,空格‘ ’,水平制表符Tab‘\t’)(均作为结束标志,并将空白符变成空字符‘\0’补充在输入的最后一个字符后面),并且在输入第一个字符前忽略所有空白符。但scanf在输入字符时,并不会忽略空白符,反而会直接接收任何空白符,因此我们在输入前应该先将容易在缓冲区留下来的空白符清除。
这里补充空字符的概念:在C语里,‘\0’是一个‘空操作’字符,它不做任何操作,但不能理解为没有字符,应该理解为代表什么都没有的字符,是一个特殊标志,默认作为字符串结束的标志。并且‘\0’的代码值为0,不计入串的长度,但需要提供一个空间存储以防数据溢出,所以常常数组大小需要至少比字符串多一位。

2.占位符为%[]
在代码中 scanf(“%[^Q] %*c%*c”, &str); 使用了两个 %*c 是为了接收字符Q和回车符号(\n)。
因为 scanf("%[^Q] ", &str);本意为除了Q字符以外的字符全部接收写入到str中。一旦遇到Q就停止匹配,并且停止匹配后Q字符和Q字符之后输入的回车符都在我们的输入缓冲区中,如果我们不对这些字符做出清理就会影响下一次的输入。
一些常见的组合用法

#include<stdio.h>
int main()
{
	char str[100];
 
//	scanf("%[^!]", str);//以!结束输入		注:记得清理缓冲区中剩余字符
//	scanf("%[^\n]",str);//以回车结束输入	注:。。。
//
//	scanf("%[123]",str);	//只能输入123,遇到其他字符后停止匹配
//	scanf("%[^123]",str);	//只能输入非123,遇到其123后停止匹配
//	
//	scanf("%[a-z,A-Z]", str);	//只能输入英文字符,遇到其他字符后停止匹配
//	scanf("%[^a-z,A-Z]",str);	//只能输入非英文字符,遇到其他字符后停止匹配
//
//	scanf("%*c",str);//清理缓冲区中第一个字符,比如:上次遗留下的\n 
//	scanf("%*[^!] %*c",str); //跳过一行 
 
	printf("%s", str);
	return 0;
 
}

int sscanf( const char *buffer, const char *format [, argument ] … );(把一个字符串转换成格式化的数据)
解释:
buffer是C字符串(可以是一个变量),表示输入流,其他见前文。
本质是scanf的输入流stdin改成了buffer,在进行输入数据时,数据来源不是键盘了,而是buffer这个字符串。
例如:

struct student{
	char name[256];
	int age;
}stu;

int main(){
	char buf[256] = "zhangsan 20";
	sscanf(buf, "%s %d", stu.name, &(stu.age));
	printf("%s %d", stu.name, stu.age);
	return 0;
}

结果为:zhangsan 20


int fscanf( FILE *stream, const char *format [, argument ]… );(针对所有输入流的格式化的输入函数)
解释:
stream是输入流名称,其他见前文。
在进行输入数据时,数据来源不一定是键盘了,而可以自定义。


int printf( const char *format [, argument]… );(-格式化的输出函数)
解释:
format是C字符串(可以是一个变量),包含了以下各项中的一个或多个
其形式为:"%[flags(标志)][width(宽度)][.prec(精度)][length(类型长度)][type(类型)]“
解释
flags:

标志 意义
- 项目是左对齐的;也就是说,会把项目打印在字段的左侧开始处。示例:“%-20s”
+ 有符号的值若为正,则显示带加号的符号;若为负,则带减号的符号。示例:“%+6.2f”
空格 带符号的值若为正,则显示时带前导空格(但是不显示符号);若为负,则带减号符号。+标志会覆盖空格标志;示例:“% 6.2f”
# 使用转换说明的可选形式。若为%o格式,则以0开始;若为%x或%X格式,则以0x或0X开始。对于所有的浮点形式,#保证了即使不跟任何数字,也打印一个小数点符号。对于%g和%G格式,它防止尾随0被删除;示例:“%#o”
0 对于所有的数字格式,用前导0而不是用空格填充字段。如果出现-标志或者指定了精度(对于整数)则忽略该标志;示例:“%010d”

width和.prec:

修饰符 意义
digit(s) 字段宽度的最小。如果该字段不能容纳要打印的数或者字符串,系统就会使用更宽的字段。示例:“%4d”
.digit(s) 精度,对于%e,%E和%f转换,是将要在小数点的右边打印的数字的位数。对于%g和%G转换,是有效数字的最大位数。对于%s转换,是将要打印的字符的最大数目。对于整数转换,是将要打印的数字的最小位数;如果必要,要使用前导0来达到这个位数。只使用".“表示其后跟随一个零,所以%.f和%.0f相同;示例:”%5.2f"打印一个浮点数,他的字段宽度为5个字符,小数点后面有两位数字

length:

修饰符 意义
h 和整数转换说明符一起使用,表示一个short int或unsigned short int类型数值;示例:“%hu” “%hd” “%hx”
hh 和整数转换说明符一起使用,表示一个signed char或unsigned char类型数值;示例:“%hhu” “%hhd” “%hhx”
j 和整数转换说明符一起使用,表示一个intmax_t或uintmax_t值;示例:“%jd” “%jX”
l 和整数转换说明符一起使用,表示一个long int或unsigned long int类型数值;示例:“%lu” “%ld”
ll 和整数转换说明符一起使用,表示一个long long int或unsigned long long int类型数值(c99);示例:“%llu” “%lld”
L 和浮点转换说明符一起使用,表示一个long double值;示例:“%Lf” “%Le”
t 和整数转换说明符一起使用,表示一个ptrdiff_t值(与两个指针之间的差对应的类型)(c99);示例:“%td”
z 和整数转换说明符一起使用,表示一个size_t值(sizeof返回类型)(c99);示例:“%zd”
I64 和整数转换说明符一起使用,表示一个_int64值

type:

转换说明 输出
%a 浮点数、十六进制数字和p-计数法(c99)
%A 浮点数、十六进制数字和P-计数法(c99)
%c 一个字符
%d 有符号十进制整数
%e 浮点数、e-记数法
%E 浮点数、E-计数法
%f 浮点数、十进制记数法
%g 根据数值不同自动选择%f或%e。%e格式在指数小于-4或者大于精度时使用
%G 根据数值不同自动选择%f或%E。%E格式在指数小于-4或者大于精度时使用
%i 有符号十进制整数(与%d相同)
%o 有符号八进制整数
%p 指针
%s 字符串
%u 无符号十进制整数
%x 使用十六进制数0x的无符号十六进制整数
%X 使用十六进制数字0X的无符号十六进制整数
%% 打印一个百分号

浮点参数的转换:

有用于打印浮点类型double和long double的转换说明符,但没有用于float的说明符。原因是在K&R C中float值在被用于表达式中或者被用作参数之前,会被自动转换成double类型。一般情况下,ANSI C不会自动把float转换成double。不过,为了保护大量现有的假设float参数仍会自动被转换成double。因此,不过是K&R C还是ANSI C,都无需专门的转换说明符来显示float。


int sprintf( char *buffer, const char *format [, argument] … );(把一个字符串转换成格式化的数据)
解释:
buffer是C字符串(可以是一个变量),表示输入流,其他见前文。
例如:

struct student{
	char name[256];
	int age;
}student= { "zhangsan", 20 };

int main(){
	char buf[256] ;
	sprintf(buf, "%s %d", student.name, student.age);
	printf("%s", buf);
	return 0;
}

结果为:zhangsan 20


int fprintf( FILE *stream, const char *format [, argument ]…);(针对所有输入流的格式化的输入函数)
解释:
stream是输入流名称,其他见前文。

猜你喜欢

转载自blog.csdn.net/phantomthief1412/article/details/121939290