前言
C语言中,许多函数的函数名过于相似,使用者要是不能很好地区分这些函数,就会造成误用,最终导致代码的结果大相径庭。对于scanf和printf函数、fscanf和fprintf函数、sscanf和sprintf函数这三对函数,它们的函数名都只是各自相差一个字母而已,但其功能及其用法却并不相同,有多少人能够真正分清楚它们各自的功能与使用方法呢?
其中,知道printf和scanf函数的人最多,其次是fprint和fscanf函数,知道sprintf和sscanf函数的人最少。本篇博文,就带大家一同认识认识这三对函数,区分它们各自的功能与使用方法。
scanf和printf函数
scanf函数和printf函数是应用于标准输入流和标准输出流的格式化输入输出语句。
一、scanf函数
scanf函数的功能是从标准输入流读入格式化的数据。
int scanf ( const char * format, ... );
从标准输入流(stdin)读取数据,并根据参数格式将它们存储到附加参数所指向的位置。附加参数应指向已分配的对象(即附加参数应是一个地址,或者说指针),这些对象的类型由格式字符串中相应的格式说明符指定。
例如,以下代码:
scanf("%d", &input);
//scanf("%d", input);//error
scanf函数以%d(整型)的格式从标准输入流读入的数据存储到&input所指向的内存空间。所以说,我们之后若是打印变量input,就会打印出已读取的这个值。
二、printf函数
printf函数的功能是将格式化的数据打印到标准输出流上去。
int printf ( const char * format, ... );
printf函数将format指向的C字符串写入标准输出流(stdout)。如果format字符串中包含格式说明符(以%开头的子序列),则format后面的附加参数将被格式化并插入结果字符串中,以替换它们各自的说明符。
我们平时已经习惯了这样使用printf函数:
printf("hello world!\n");//第一种写法
其实传入printf函数的参数本质上是一个指向字符串的指针,于是我们这样写也是没问题的:
char arr[] = "hello world!\n";
printf(arr);//第二种写法
第一种写法中,直接将一个字符串传入printf函数,实际上也是将该字符串的首地址传入了函数,本质上与第二种写法相同,所以那样写也是没有问题的。
fscanf和fprintf函数
fscanf函数和fprintf函数是应用于所有输入流和所有输出流的格式化输入输出语句。
fscanf函数和fprintf函数是一对文件操作函数,在博主的文件操作函数(二)中有详细介绍,这里就不再详细介绍。
既然说fscanf函数和fprintf函数是应用于所有的标准输出流和标准输入流的函数,那么这对函数的功能也就包含了printf函数和scanf函数的功能。我们完全可以用fscanf函数和fprintf函数来做scanf函数和printf函数做的事。
一、fscanf函数实现scanf函数的功能
int fscanf( FILE *stream, const char *format [, argument ]... );
因为fscanf函数的功能是,从stream中读取数据,并根据参数格式将其存储到附加参数所指向的位置,所以我们只需将参数stream的位置传入stdin,使其在标准输入流中读取数据即可。
所以,下面两句代码的作用是等效的:
scanf("%d", &input);
fscanf(stdin, "%d", &input);
二、fprintf函数实现printf函数的功能
int fprintf( FILE *stream, const char *format [, argument ]...);
因为fprintf函数的功能是,将格式化数据写入stream中,所以我们只需将参数stream的位置传入stdout,使其将数据写入标准输出流即可。
所以,下面两句代码的作用是等效的:
printf("%d\n", input);
fprintf(stdout, "%d\n", input);
三、拓展
我们之前在介绍文件操作函数的时候就说过,当你要对某一个流进行输入或是输出操作的时候,首先要打开该流,当输入输出操作结束后要及时关闭该流。
既然printf函数和scanf函数也要对标准输入流和标准输出流进行操作,那么为什么在使用printf函数和scanf函数之前,并没有类似于打开文件流的fopen函数的使用,在使用完printf函数和scanf函数后又没有类似于关闭文件流的fclose函数的使用呢?
其实,当C程序运行起来的时候,会自动打开下面这三个流:
符号 | 名称 | 对应操作(显示)位置 |
---|---|---|
stdin | 标准输入流 | 键盘 |
stdout | 标准输出流 | 屏幕 |
stderr | 标准错误流 | 屏幕 |
而当程序运行结束后,这三个流又会自动关闭。所以,当我们需要对标准输入流或是标准输出流进行输入输出操作的时候,并不需要通过某些操作来打开这两个流,也不需要我们来关闭这两个流。
sscanf和sprintf函数
sscanf函数可以从字符串中读取格式化数据,sprintf函数可以将格式化数据写入字符串。
一、sscanf函数
int sscanf ( const char * s, const char * format, ...);
sscanf函数从s读取数据并根据参数格式将其存储到附加参数给定的位置,就像使用scanf一样,但sscanf函数是从s读取数据而不是标准输入(stdin)。
例如,我们要将字符串arr里面的内容按照不同的格式读取出来。
#include <stdio.h>
int main()
{
char arr[] = "2021 dragon";
int year = 0;
char s[10] = {
0 };
sscanf(arr, "%d %s", &year, s);
printf("%d\n", year);//2021
printf("%s\n", s);//dragon
return 0;
}
也就是将从区域一中,以区域二的格式读取的数据,存储到区域三指向的空间。
二、sprintf函数
int sprintf ( char * str, const char * format, ... );
sprintf函数与printf函数功能相似,区别在于:printf函数是将数据格式化后直接打印在屏幕上,而sprintf函数是将数据格式化后存储在str所指向的字符串中。
例如,将数据按照不同的格式写入字符串arr中。
#include <stdio.h>
int main()
{
char arr[20] = {
0 };
int year = 2021;
char s[] = "dragon";
sprintf(arr, "%d %s", year, s);
printf("%s\n", arr);//2021 dragon
return 0;
}
也就是将从区域三中,以区域二的格式读取的数据,存储到区域一指向的位置。
总结
函数 | 功能 |
---|---|
scanf,printf | 应用于标准输入流和标准输出流的格式化输入输出语句。 |
fscanf,fprintf | 应用于所有输入流和所有输出流的格式化输入输出语句。 |
sscanf,sprintf | 应用于字符串和格式化数据之间的相互转换 |
转载:https://blog.csdn.net/chenlong_cxy/article/details/115188839