C 语言]全面了解常用格式化函数 - 格式化输出
1.printf()函数
函数原型:
int printf(const char *format, ...);
函数说明:
printf函数的调用格式为:printf("<格式化字符串>", <参量表>);
格式化字符串(format)中包含两部分:一是正常字符,按照原样输出;二是以%开始的可控字符,由参量表中的内容决定。参量表就是一系列需要输出的参数,可以有多个参数,各个参数之间用","分开,并且与格式化字符串中的可控字符的个数一一对应。
返回值:对于绝大部分初学者来说几乎没人去关心printf的返回值,甚至说有一部分人可能都不知道它有返回值,但是从函数原型中我们可以看到它确实是有的,printf函数的返回值就是输出的字符数量,该数量包括数字,字母,标点符号,空格和换行等。
下面通过一个例子来说明,想必对printf函数就会很清楚了,同时也会对同时也会对上面的控制字符有清晰地认识。
#include <stdio.h>
int main(void)
{
printf("%3d\n",12345);
printf("%9d\n", 123);
printf("%09d\n", 123);
printf("%-9d\n", 123);
printf("%+9d\n", 123);
printf("%-+9d\n", 123);
printf("%+-9d\n", 123);
printf("%9.2f\n", 123.0);
printf("%*d\n", 6, 123);
//测试printf的返回值
int num = 12345;
int i1 = printf("%d\n", num);
int i2 = printf("%d", num);
printf("\ni1 = %d\ti2 = %d\n", i1, i2);
return 0;
}
运行结果:
结果分析:
通过前面的表可以知道,width中的number是最小的字符数,它的意思是:如果实际输出的位数不够,则会补齐位数,如果实际输出位数比它大,则原样输出,如运行结果中的第一二行。其它的大家应该都能看懂,我来解释一下printf("%*d\n", 6, 123);
*
表示下一个参数是字符数,于是这个语句其实等价于printf("%6d\n", 123);
通过运行结果我们也可以看出来,最后确实是输出了6个字符。那么这样做有什么好处呢?这样做的话,我们就可以通过使这个参数为变量,从而让整个程序更为灵活,而且这个变量也可以让用户自己输入。即代码变成printf("%*d\n", number, 123);
。最后我们来看printf的返回值,我们知道printf返回的是输出的字符个数,i1=6
,i2=5
,是因为i1多打印了一个换行符,所以如果你想使用printf的返回值必须对换行符制表符加以注意,因为那也是一个字符。
2.sprintf函数
函数原型:
int sprintf(char *str, const char *format, ...);
函数说明:
sprintf函数的主要功能是把格式化的数据(format)写入某个字符串中,即发送格式化输出到string所指向的字符串。
函数调用形式:sprintf(str, “<格式字符串>”, <参量表>);
从函数原型中可以看出sprintf和printf十分相似,对于相同的部分,在此不再赘述。不同之处在于多了一个指向char类型的指针str,通常情况下我们会定义一个字符数组,它的作用是存储字符串。
返回值:函数调用成功则返回字符串长度(这个长度并不包括字符串末尾的空字符),如果失败则返回一个负数。注意:使用该函数要避免堆栈溢出,或选择使用更为安全的snprintf函数。
下面进行代码分析:
#include <stdio.h>
int main(void)
{
int x = 123;
int i = 0;
char str[10] = {0};
i = sprintf(str, "%d", 123);
printf("str = %s\ti = %d\n", str, i);
return 0;
}
//运行结果:
str = 123 i = 3
结果分析:
运行的结果如我们所设想的那样,123被存放到str的数组中,并且函数的返回值也正是字符个数。对于不同的打印格式这里就不再演示,可以参照printf函数部分的代码。
注意,请读者试着编译运行下方代码,观察运行结果是否如你所想
sprintf(str, "%.2f", 123);
printf("str = %s", str);
3.fprintf函数
函数原型:
int fprintf(FILE *stream, const *format, ...);
函数说明:
fprintf函数主要作用是格式化输出到一个流文件中,即将指定格式(format),输入到stream中去。
函数调用形式:sprintf(str, “<格式字符串>”, <参量表>);
通过函数原型我们可以知道fprintf函数与sprintf函数很相似,区别就是sprintf是向字符数组写入数据,fprintf则是向文件写入数据,具体的实现方法,则是通过向指向FILE的指针,写入数据。
返回值:成功返回输出的字节数,失败返回EOF(end of file)。
下面进行代码分析:
#include <stdio.h>
int main(void)
{
int i;
FILE *stream = fopen("123.txt", "w");
i = fprintf(stream, "%d", 123456);
printf("i = %d\n", i);
return 0;
}
//运行结果
i = 6
运行结果:
结果分析:
123456被成功的输入到123.txt文件中了, 函数的返回值i=6。对于fopen函数可能有些人不是很了解,由于本文主要说的是格式化输入输出函数,所以不会在此展开,后面会专门写一篇关于文件操作的函数。
格式化输入函数
1.scanf函数
函数原型:
int scanf(const char *format,...);
函数说明:
scanf函数是从标准输入流中读取内容,并将其保存在对应的地址中。
函数调用形式:scanf("<格式化字符串>",<地址表>);
scanf函数和printf函数是很相似的,对于初学者来说,它们也是使用率极高的两个函数,所以他们的使用方法都大致相同,在此提一下,在写地址标的变量时,一定不要忘记取址符&,同时它还有一个比较特殊但是很有用的格式控制字符[]
,它的作用是扫描字符集合,具体后面会上代码进行解释。
返回值: 返回成功读入的数据个数,如在读入数据时遇到“文件束”则返回EOF。
其实关于scanf函数可以说的有很多,但是由于篇幅原因,本文会选择经常容易出现的错误来举例,不会说得十分详细,有兴趣的小伙伴可以自行查阅资料,或者在下方进行评论。
下面进行代码分析_1:
#include <stdio.h>
int main(void)
{
int x, y, z;
scanf("%d%d%d", &x, &y, &z);
printf("x = %d\ty = %d\tz = %d\n", x, y, z);
return 0;
}
结果分析:
//一下输入方式都合法,分别输入2/3/4代表x/y/z
2 3 4
2 3 4
2
3
4
//输出结果都为:
x = 2 y = 4 z = 6
//原因分析
scanf函数会在操作中略去一个或多个空白符,直至出现第一个非空白符为止,所以以上输入方式都是可以的
下面进行代码分析_2:
//只附上关键部分代码
scanf("%d,%d,%d", &x, &y, &z);
scanf("x=%d,y=%d,z=%d",&x, &y, &z);
结果分析:
//scanf的格式控制字符串可以有其它非空白符,但是在输入时必要将这些字符按照相同的一并输出
//下列输入是合法的
//对于第一句scanf
3,4,5/3, 4,5/
3,
4, 5/
//对于第二句scanf
x=3,y=4,z=5/x=3, y=4,z=5/
//下列语句是不合法的
3 , 4 ,5
x =3, y=4 , z= 5
此外你可能会有所疑问,如果我想输入一段英文文字,那么它是如何判定我这个是一句话还是一段话呢?答案是无法判定,scanf函数会自动略去空白符,所以它就只能读取你的第一个单词,那么这样一来我们是不是就无法输入一段文字呢?答案当然是可以输入的,这是就需要用到前面说的一种控制字符[]
,具体的效果及使用方法看代码。
#include <stdio.h>
int main(void)
{
char str1[40];
char str2[40];
char str3[40];
scanf("%s", str1);
printf("%s\n",str1);
scanf("%[^\n]s", str2);
printf("%s\n",str2);
scanf("%[abcd]s", str3);
printf("%s\n",str3);
return 0;
}
代码分析:
//[]放在%的后面,常见的用法有两种一种是里面有'^'符号,一种是没有。
//前者代表,scanf会将空白符一起读入。
//后者代表,scanf会连续读入输入值,直到出现不在[]中间的字符为止。
//对于第一个scanf
输入:hello world
输出:hello
//对于第二个scanf
输入:hello world
输出:hello world
//对于第三个scanf
输入:abdlhfg
输出:ab
输入:sdgafsdgacacb
输出:
2.sscanf函数
函数原型:
int sscanf(const char *buffer, const char *format,...);
函数说明:
sscanf与scanf函数类似,区别在于前者是以指定字符串作为输入,后者是以键盘作为输入。
函数调用形式:sscanf(<存储的数据>, “<格式字符串>”, <存储的位置>);
返回值:返回成功赋值的个数,如果在第一次读取之前到达字符串结尾则返回EOF,失败返回-1。
演示代码:
#include <stdio.h>
int main(void)
{
char str[100];
sscanf("123abc", "%5s", str);
printf("%s\n", str);
return 0;
}
//运行结果:
123ab //%5s限定了字符串的长度。
3.fscanf函数
函数原型:
int fscanf(FILE *stream, const char *format,...);
函数说明:
fscanf与sscanf函数类似,区别在于前者是以文件作为输入,后者是以指定字符串作为输入。
函数调用形式:fscanf(<输入流>, “<格式字符串>”, <存储的位置>);
返回值:返回成功读入参数的个数,失败返回EOF(-1)。
演示代码:
#include <stdio.h>
int main(void)
{
char str[30];
int x;
FILE *fp = fopen("1234.txt", "r");
fscanf(fp, "%s %d", str, &x);
printf("str = %s\tx = %d\n", str, x);
return 0;
}
//运行结果:
预先在1234.txt文件中输入了如下内容:123456 789
程序运行的结果;
str = 123456 x = 789
数调用形式:fscanf(<输入流>, “<格式字符串>”, <存储的位置>);
返回值:返回成功读入参数的个数,失败返回EOF(-1)。
演示代码:
#include <stdio.h>
int main(void)
{
char str[30];
int x;
FILE *fp = fopen("1234.txt", "r");
fscanf(fp, "%s %d", str, &x);
printf("str = %s\tx = %d\n", str, x);
return 0;
}
//运行结果:
预先在1234.txt文件中输入了如下内容:123456 789
程序运行的结果;
str = 123456 x = 789
注:本文的六个函数头文件均为<stdio.h>。
上一篇: C++ 实例 – 求一元二次方程的根 |