转自 http://blog.csdn.net/todd911/article/details/8952565
输入输出函数家族
家族名 目的 可用于所有的流 只用于stdin和stdout
getchar 字符输入 fgetc,getc getchar
putchar 字符输出 fputc,putc putchar
gets 文本行输入 fgets gets
puts 文本行输出 fputs puts
scanf 格式化输入 fscanf scanf
printf 格式化输出 fprintf printf
注意点:
fgetc和fputc都是真正的函数,但是getc,putc,getchar和putchar都是通过#define指令定义的宏,
所以在调用getc,putc,getchar和putchar时不能使用具有副作用的参数。
fgets的用法如下:
CHAR *fgets(CHAR *string,int n,FILE *stream);
fgets()用来从参数stream所指的文件内读入字符并存到参数string所指的内存空间,直到出现换行字符、读到文件尾或是已读了n-1个字符为止,最后会加上NULL作为字符串结束。如果在未读满n-1个字符之时,读到一个换行符或一个EOF(文件结束标志),则结束本次读操作,读入的字符串中最后包含读到的换行符,再有一个字符为NULL。如果string无法存放整行,则下一次调用fgets时将从stream的下一个字符开始读取,不会出现数据丢失的情况。
fputs向指定的文件写入一个字符串(不自动写入字符串结束标记符‘\0’)
gets从stdin流中读取字符串,直至接受到换行符或EOF时停止,并将读取的结果存放在str指针所指向的字符数组中。换行符不作为读取串的内容,读取的换行符被转换为null值,并由此来结束字符串。
gets函数不安全,没有限制输入缓冲区的大小,容易造成溢出,所以尽量不要使用gets。
关于gets危害:
本人写的程序如下:
1 #include <stdio.h>
2 int main(void)
3 {
4 char name[10];
5 gets(name);
6 puts(name);
7 }
这个程序最简单不过了,就是一个字符串输出输入的问题,但是使用linux下的gcc编译老是不能通过,提示的问题是:
“the 'gets' function is dangerous and should not be used.”
让我很纠结,为什么这个函数不让使用,它怎么就危险了?
然后我又查阅了linux C函数库之后就明白了。书上为这个函数附加了一条说明:“由于gets()无法知道字符串的大小,必须遇到换行字符或文件尾才会结束输入,因此容易造成缓存溢出的安全性问题。建议使用 fgets()取代。”
原来gcc为了安全考虑就直接把gets()函数的使用权给取消了。下面是net小伙用windows下的vc编译的一个小程序,来说明gets()究竟有什么危害。
程序如下:
#include <stdio.h>
int main(void)
{
char a;
char name[];
char b;
scanf("%c",&a);
printf("a:%c\n",a); //第一次输出a的值
getchar();
gets(name);
scanf("%c",&b);
printf("name:%s;\na:%c;\nb:%c;\n",name,a,b); //输出所有的值,注意a
}
由于我们把字符串改成了“this is a text”
然后a的值莫名其妙的被替换了。紧接着编译器不能正常工作了。
在不正确使用gets()函数的时候造成的危害是很大的,就像我们刚才看到的那样,a的值被字符串name溢出的值给替换了。我想这并不是你想要的结果吧!出于安全,用fgets()来代替gets()吧!