C语⾔——格式化输⼊和输出函数
格式化输⼊和输出函数
⼀、printf、fprintf 和sprintf函数
函数原型:
#include <stdio.h>
int printf(const char *format, ...);
int sprintf(char *s, const char *format, ...);
int fprintf(FILE *stream, const char *format, ...);
函数说明:
printf系列函数能够对这种不同类型的参数进⾏格式编排和输出。format参数控制输出的格式。
printf函数,print format的简写,作⽤是把⾃⼰的输出送到标准输出。
sprintf函数,string print format的简写,作⽤是把⾃⼰的输出和⼀个结尾空字符写到作为参数传递过来的字符串s⾥。这个字符串必须⾜够容纳所有的输出数据。
fprintf函数,file print format的简写,作⽤是把⾃⼰的输出送到⼀个指定的⽂件流。
常⽤的转换控制符:
转换控制符转换控制符说明
%d,%i以⼗进制格式输出⼀个整数
%o,%x以⼋进制或⼗六进制格式输出⼀个整数
%c输出⼀个字符
%s输出⼀个字符串
%f输出⼀个(单精度)浮点数
%e以科学计数法格式输出⼀个双精度浮点数
%g以通⽤格式输出⼀个双精度浮点数
%%读取⼀个%字符
例:
char initial = ‘A’;
char *surname = "Matthew";
double age = 13.5;
printf("Hello Mr %c, %s, aged %g\n", initial, surname, age);
字段限定符:
格式化命令format参数字段限定符说明
%10s右对齐输出字符串
%-10s左对齐输出字符串
%10d右对齐输出整数
%-10d左对齐输出整数
%010d整数前的空位补0
%010d整数前的空位补0
字段限定符说明
%10.4f右对齐输出浮点数,精确到⼩数点后4位
%*s输出⼀个可变长度的字符串
"-":左对齐格式输出
“*”:可变字段宽度
0:0开头表⽰数据前⾯⽤0填充。
注意:
1.函数中的参数数⽬和类型必须与format字符串⾥的转换控制符匹配。
2.整数参数的类型可以⽤⼀个可选长度限定符来指定。它可以是h、l,例如%hd表⽰⼀个短整数,%ld表⽰这是⼀个长整数。使⽤gcc编译器,可以在编译命令中加-Wformat选项实现这⼀功能。
返回值说明:
printf函数返回的是输出的字符个数。sprintf的返回值⾥没有算上结尾的null空字符。如果发⽣错误,这些函数会返回⼀个负值并设置errno。
⼆、scanf、fscanf 和 sscanf函数
函数原型:
#include <stdio.h>
int scanf(const char *format, ...);
int fscanf(FILE *stream, const char *format, ...);
int sscanf(const char *s, const char *format, ...);
函数说明:
scanf系列函数的⼯作⽅式与printf系列函数相似,作⽤是从⼀个⽂件流⾥读取数据,并把数据值放到以指针参数形式传递过来的地址处的变量中。它们也使⽤⼀个格式字符串来控制输⼊数据的转换,它所使⽤的许多转换控制符都与printf系列函数⼀样。
scanf函数,scan format的简写,作⽤是将读⼊的值保存到对应的变量中,这些变量必须是正确的,并且必须精确匹配格式字符串。否则,内存数据就可能遭到破坏,从⽽使程序崩溃。
转换控制符:
转换控制符说明
%d读取⼀个⼗进制整数
%o,%x读取⼀个⼋进制或⼗六进制整数
%c读取⼀个字符,它不会跳过起始的空⽩字符
%s读取⼀个字符串,它会跳过起始的空⽩字符
%f、%e、%g读取⼀个浮点数
%[]读取⼀个字符集合
%%读取⼀个%字符
%hd读⼊⼀个短整数
%ld读⼊⼀个长整数
%lg读⼊⼀个双精度浮点数
返回值说明:
scanf函数的返回值是它成功读取的数据项个数,如果在读第⼀个数据项时失败了,它的返回值就将是0.如果在匹配第⼀个数据项之前就已经到达了输⼊的结尾,它就会返回EOF。如果⽂件流发⽣错误,流错误标志就会被设置并且errno将被设置以指明错误类型。
注意:
1.输⼊的空⽩字符在进⾏数据转换时⼀般会被忽略。
2.以“*”开头的控制符表⽰对应位置上的输⼊数据将被忽略。这意味着,这个数据不会被保存,因此不
需要使⽤⼀个变量来接收它。
3.使⽤%s控制符来扫描字符串时要⼩⼼,它会跳过起始的空⽩字符,在字符串⾥出现的第⼀个空⽩字符处停下来,所以最好⽤它来读取单词⽽不是⼀般意义上的字符串。此外,如果没有使⽤字段宽度限定符,它能够读取的字符串的长度是没有限制的,所以接收字符串必须有⾜够的空间来容纳输⼊流中可能的最长字符串。较好的选择是使⽤⼀个字段限定符,或者结合使⽤fgets和sscanf从输⼊读⼊⼀⾏数据,再对它进⾏扫描。这样可以避免可能被恶意⽤户利⽤的缓冲区溢出。
4.使⽤%[]控制符读取由⼀个字符集合中的字符构成的字符串。格式字符串%[A-Z]将读取⼀个由⼤写字母构成的字符串。如果字符串中第⼀
,就表⽰将读取⼀个由不属于该字符集合中的字符构成的字符串。因此,读取⼀个其中带空格的字符串,并且在遇到第⼀个逗号时停⽌,可以⽤%[
个字符是,]。
scanf系列函数缺点:
具体实现有漏洞。
使⽤不够灵活。
使⽤它们编写的代码不容易看出究竟正在解析什么。
可以尝试使⽤其他函数,如fread或fgets来读取输⼊⾏,再⽤字符串函数把输⼊分解成需要的数据项。
例:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int c;
FILE *in,*out;
in = fopen("file.in","r");
out = fopen("file.out","w");
while((c = fgetc(in)) != EOF)
{
FPUTC(C,out);
}
exit(0);
}
三、其他流函数
1.fgetpos函数
获取⽂件流的当前(读写)位置。
2.fsetpos函数
设置⽂件流的当前(读写)位置。
3.ftell函数
返回⽂件流当前(读写)位置的偏移量
重置⽂件流⾥的读写位置
5.frepoen函数
重新使⽤⼀个⽂件流
6.setvbuf函数
设置⽂件流的缓冲机制
相当于unlink函数,但如果它的path参数是⼀个⽬录的话,其作⽤就相当于rmdir函数。
四、⽂件流错误
为了表明错误,许多stdio库函数会返回⼀个超出范围的值,⽐如空指针或EOF常数。错误由外部变量errno指出:
#include <errno.h>
extern int errno;
注意:很多函数都可能改变errno的值。它的值只有在函数调⽤失败时才有意义。必须在函数表明失败后⽴刻对其进⾏检查,应该总是在使⽤它之前先将它先复制到另⼀个变量中。
可以通过检查⽂件流的状态来确定是否发⽣了错误,或者是达到了⽂件尾。
函数原型:
#Include <stdio.h>
int ferror(FILE *stream);
int feof(FILE * stream);
void clearerr(FILE *stream);
1.ferror函数说明
测试⼀个⽂件流的错误标识,如果该标识被设置就返回⼀个⾮零值,否则返回零。
2.feof函数说明
测试⼀个⽂件流的⽂件尾标识,如果该标志被设置就返回⾮零值。
3.clearerr函数说明
作⽤是清除由stream指向的⽂件流的⽂件尾标识和错误标识。它没有返回值,也未定义任何错误。可以通过使⽤它从⽂件流的错误状态中恢复。例如,在“磁盘已满”错误解决之后,继续开始写⼊⽂件流。
五、⽂件流和⽂件描述符
每个⽂件流都和⼀个底层⽂件描述符相关联。可以把底层的输⼊输出操作与⾼层的⽂件流操作混合使⽤,但不是很好,因为数据缓冲的后果难以预料。
函数原型:
#include <stdio.h>
int fileno(FILE *stream);
FILE *fdopen(int fildes,const char *mode);
1.fileno函数
作⽤是确定⽂件流使⽤的是哪个底层⽂件描述符。它返回指定⽂件流使⽤的⽂件描述符,如果失败就返回-1.如果你需要对⼀个已经打开的⽂件流进⾏底层访问时(例如,对它调⽤fstat),这个函数会很有⽤。
2.fdopen函数
操作⽅式与fopen函数⼀样,只是fdopen的参数不是⼀个⽂件名,⽽是⼀个底层的⽂件描述符。如果已经通过open系统调⽤创建了⼀个⽂件(可能是出于为了更好地控制其访问权限的⽬的),但⼜想通过⽂件流来对它进⾏写操作,这个函数就很有⽤了。fdopen函数的mode参数与fopen函数的完全⼀样,但它必须符合该⽂件再最初打开是所设定的访问模式。fdopen返回⼀个新的⽂件流,失败时返回NULL。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论