fgets、gets与fputs、puts

我们知道着两个函数都提供每次输入一行的功能。然而gets是一个不推荐使用的函数,其原因是使用gets不能指定缓冲区的长度,这样就可能造成缓冲区的溢出。除了gets只能操作标准输入(stdin)外,gets和fgets还有另一个区别——gets并不将换行符读入缓冲区中。例如:输入”abcde\n”,那么gets时缓冲区中只用”abcde”而没有”\n”。相反fgets则会完整的读入”abcde\n”。

与此对应,puts因为一般和gets成对使用,所以puts输出以NULL结尾的字符串后(NULL不输出),会另外将一个换行符也输出到标准输出。

我们先看下面程序段:

程序段1:

char buf[BUFSIZE];

while( fgets(buf,BUFSIZE,stdin)!=NULL )

if( fputs(buf,stdout)==EOF )

printf("output error!\n");

输出:

结论:fgets和fputs结合使用正常工作

分析:输入”abcdef\n”,fgets读入”abcdef\n”到缓冲区,fputs将”abcdef\n”从缓冲区中取出输出。

程序段2:

char buf[BUFSIZE];

while( gets(buf)!=NULL )

if( puts(buf)==EOF )

printf("output error!\n");

输出:

结论:gets和puts结合使用正常工作

分析:输入”abcdef\n”,gets读入”abcdef”到缓冲区(注:不读入’\n’),puts将”abcdef”从缓冲区中取出输出,之后又将一个换行符(‘\n’)输出到标准输出,即gets不读入换行符,而puts增加换行符。

程序段3:

char buf[BUFSIZE];

while( gets(buf)!=NULL )

if( fputs(buf,stdout)==EOF )

printf("output error!\n");

输出:

结论:gets和fputs结合使用不能正常工作

分析:输入”abcdef\n”,gets读入”abcdef”到缓冲区(注:不读入’\n’),fputs将”abcdef”从缓冲区中取出输出(并没有增加换行符),所以下一行的输入会和上个输出在同一行,即造成输出比输入少一个换行符。

程序段4:

char buf[BUFSIZE];

while( fgets(buf,BUFSIZE,stdin)!=NULL )

if( puts(buf)==EOF )

printf("output error!\n");

输出:

结论:fgets和puts结合不能正常工作

分析:输入”abcdef\n”,fgets读入”abcdef\n”到缓冲区,puts将”abcdef\n”从缓冲区中取出输出(这里已经有一个换行符),之后又将一个换行符输出,所以造成输出比输入多一个换行符(输出两个换行符)。

总结:应该尽量使用fgets和fputs,一方面是比较安全,两一方面保持输入输出的原样性,不必去记忆对换行符的处理。

fgets、gets与fputs、puts

时间: 2024-12-10 21:59:14

fgets、gets与fputs、puts的相关文章

fscanf函数和fprintf函数、fgets函数和fputs函数、fread函数和fwrite函数

1. fscanf 函数和 fprintf 函数 1.1 fscanf 函数 fscanf 函数只能从文本文件中按格式输入.fscanf 函数和 scanf 函数相似,只是输入的对象是磁盘上文本文件的数据.函数的调用形式如下: fscanf( 文件指针,格式控制字符串,输入项表 ); 例如,若文件指针 fp 指向一个已打开的文本文件,a.b 分别为整型变量,则以下语句从 fp 所指的文件中读入两个整数放入变量 a 和 b 中: fscanf( fp, "%d%d", &a, &

fgets函数和fputs函数的区别

#include <stdio.h> #define MAXLINE 20 int main(void) { char line[MAXLINE]; while (fgets(line,MAXLINE,stdin)!=NULL && line[0] != '\n') fputs(line,stdout); return 0; } fgets()函数是用于存储输入的地址(char *类型).第二个参数为整型,表示输入字符串的最大长度.最后与一个参数是文件指针,指向要读取的文件 f

fgets()函数以及fputs()函数

fgets() fgets() 该函数是一个文件操作相关的函数 暂时使用这个函数可以从键盘接收一个字符串,保存到字符数组中 原来接收字符串保存到数组中的方法: char str[50]; 1) scanf("%s",str); //缺点:不能接收空格 2)gets(str); //优点:可以接收空格 //缺点:会有一个不安全的警告 fgets()是一个安全的字符串接收的函数 char ch[5];//如果使用fgets,此时数组中最多存放4个可见字符 //会自动的把数组的最后一个元素存

fgets和scanf的区别

fgets和scanf的区别 1.测试使用scanf的一个例子: [cpp] view plaincopyprint? #include "stdio.h" #include "string.h" int main() { char name[10]; scanf("%s", name); puts(name); return 0; } 编译.调用如下: 可以看到第二次,由于输入的字符串长度,导致Abort 2.同样的一个fgets的例子: [c

C语言输入语句scanf与fgets linux下

1.测试使用scanf的一个例子: #include "stdio.h" #include "string.h" int main() { char name[10]; scanf("%s", name); puts(name); return 0; } 编译.调用如下: 可以看到第二次,由于输入的字符串长度,导致Abort 2.同样的一个fgets的例子: #include "stdio.h" #include "

Android系统开发(7)——标准I/O与文件锁

一.常用函数 fopen: FILE *fopen(const char *filename, const char *mode); fread: size_t  fread(void *ptz, size_t size, size_t nitems, FILE *stream); fwrite: size_t fwrite(const void *ptz, size_t size, size_t nitems, FILE *stream); fclose: int fclose(FILE *s

文件I/O与标准I/

一.先来了解下什么是文件I/O和标准I/O: 文件I/O:文件I/O称之为不带缓存的IO(unbuffered I/O).不带缓存指的是每个read,write都调用内核中的一个系统调用.也就是一般所说的低级I/O--操作系统提供的基本IO服务,与os绑定,特定于linix或unix平台. 标准I/O:标准I/O是ANSI C建立的一个标准I/O模型,是一个标准函数包和stdio.h头文件中的定义,具有一定的可移植性.标准I/O库处理很多细节.例如缓存分配,以优化长度执行I/O等.标准的I/O提

标准IO与文件IO 的区别【转】

本文转载自:http://blog.sina.com.cn/s/blog_63f31f3401013jrn.html 先来了解下什么是标准IO以及文件IO. 标准IO:标准I/O是ANSI C建立的一个标准I/O模型,是一个标准函数包和stdio.h头文件中的定义,具有一定的可移植性.标准IO库处理很多细节.例如缓存分配,以优化长度执行IO等.标准的IO提供了三种类型的缓存. (1)全缓存:当填满标准IO缓存后才进行实际的IO操作.         (2)行缓存:当输入或输出中遇到新行符时,标准

标准管道的使用

FILE * popen ( const char * command , const char * type ); 第一个参数是命令,不是文件名 popen() 函数通过创建一个管道,调用 fork 产生一个子进程,执行一个 shell 以运行命令来开启一个进程.这个进程必须由 pclose() 函数关闭,而不是 fclose() 函数.pclose() 函数关闭标准 I/O 流,等待命令执行结束,然后返回 shell 的终止状态.如果 shell 不能被执行,则 pclose() 返回的终止

Linux编程---I/O部分

非常多函数都能够在网上找到,也比較基础,所以原型仅仅给出了函数名.详细用到再man吧. 输入输出是个非常重要的一块内容.差点儿网络相关的东西基本都是靠底层IO调用来实现的. 好吧.还是先踏踏实实的介绍一下C标准库中的IO函数吧.个别函数我也是第一次见.对于不太常见的我就多解释一下,反正通常这些函数百度一下就清楚了,我就不多解释了~ 1.C标准库IO函数 1.1流的关闭开启与重定向 fopen:打开一个流 fclose:关闭一个流 freopen:又一次打开一个流 1.2 读与写 读: fgetc