C Primer Plus 第13章 文件输入/输出 13.4 文件输出/输入函数

本文详细介绍了C语言中文件输入输出的基本函数,包括fprintf()、fscanf()、fgets()和fputs()等函数的使用方法及注意事项。通过具体实例展示了如何使用这些函数进行文件的读写操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

与getc()和putc()相似,这些函数要求您使用指向FILE的指针(如stdout),或者使用fopen()函数的返回值来指定文件。

13.4.1  fprintf()和fscanf()函数

文件I/O函数fprintf()和fscanf()的工作方式与printf()和scanf()相似,区别在于前两者需要第一个参数来指定合适的文件。程序清单13.3演示了这两个文件I/O函数以及rewind()函数的使用:

程序清单13.3  addaword.c程序

/*addaword.c  使用fprintf()、fscanf()、和rewind()函数*/
#include <stdio.h>
#include <stdlib.h>
#define MAX 40
int main(void)
{
    FILE * fp;
    char words[MAX];

    if((fp=fopen("words","a+"))==NULL)
    {
        fprintf(stdout,"Can't open \"words\" file.\n");
        exit(1);
    }
    puts("Enter words to add to the file;press the Enter");
    puts("key at the beginning of a line to terminate.");
    while(gets(words)!=NULL && words[0] != '\0')
        fprintf(fp,"%s",words);
    puts("File contents: ");
    rewind(fp);/*回到文件的开始处*/
    while(fscanf(fp,"%s",words)==1)
        puts(words);
    if(fclose(fp)!=0)
        fprintf(stderr,"Error closing file\n");
    return 0;
}

通过该程序可以向文件中加入单词,使用"a+"模式,程序可以对文件进行读写操作。第一次使用该程序的时候会创建一个words文件以供添加单词。在随后 的使用中 ,可以向以前的内容后面添加单词。追加模式只能向文件结尾添加内容,但"a+"模式可以读取整个文件rewind()命令使程序回到文件开始处,这样最后wihle循环就可以打印文件的内容。注意rewind()函数接受一个文件指针参数

如果您键入一个空行,gets()函数将数组的第一个元素置为 空字符,程序据此终止循环。

正如您所看到的,fpintf()和fscanf()函数与printf()和scanf()函数工作方式类似。与putc()不同,fprintf()和fscanf()函数将FILE指针作为第一个参数而不是最后一个参数。

13.4.2  fgets()和fputs()函数

fgets()函数接受3个参数,而gets()函数只接受1个参数。第1个参数和gets()一个,是用于存储输入的地址(char *类型)。第2个参数为整数,表示输入字符串的最大长度。最后一个参数是文件指针,指向要读取的文件。下面是一个函数调用的例子:

fgets(buf,MAX,fp);

这里buf是一个char数组的名称,MAX是字符串的最大长度,fp是一个FILE指针 。

fgets()函数读取到它 所遇到的第一个换行符的后面或者读取 比字符串最大长度少一个的字符,或者 读取到文件的结尾。然后,fgets()向末尾添加一个空字符以构成一个字符串。所以, 字符串的最大长度代表字符的最大数目再加上一个空字符如果fgets()函数在达到字符最大数目之前读完了一整行,它将在字符串的空字符之前添加一个换行符以标识一行结束。这是fgets()和gets()的不同之处,后者读取换行符之后将其丢弃。

与gets()类似 ,fgets()遇到 EOF的时候会返回NULL值,可以据此检查文件结尾。否则 ,它返回传递给它的地址值 。

fputs()函数接受两个参数,它们依次是一个字符串的地址和一个文件指针。它把字符串地址所指的字符串写入到指定的文件。与puts()不同,fputs()在打印的时候并不添加一个换行符。下面是函数调用的例子。

fputs(buf,fp);

这里buf是字符串地址,fp指向目标文件。

由于fgets()函数保留了换行符,而fputs()函数不会添加换行符,所以它们配合的相当好。程序清单13.4是利用这两个函数实现的一个回显程序。

程序清单13.4  parrot.c程序

/*parrot.c  --使用fputs()和fgets()函数*/
#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;
}

程序运行良好,这看起来似乎很让人吃惊。因为输入的第二行包含了44个字符,而line数组中只能容纳20个字符(包括换行符在内)。到底怎么回事?当fgets()函数读取第二行时,它只读入前19个字符,直到down中的w。它把这些字符复制到line数组中,由fputs()函数进行打印。由于fgets()还没有遇到行尾,line数组中不包含换行符,所以fputs()函数也就不会打印换行符。第三次调用时,fgets()函数在第二次调用停下的地方重新开始,因此它把接下来的19个字符(从down中w后面的n开始)读取到数组line中。这一块内容代替了line数组中以前的内容,然后依次打印到与上次输出相同的那一行上,因为上次的输出不包含换行符。

一句话,fgets()函数每次读取第二行的19个字符,然后fputs()函数以同样的长度块将其打印。

如果一行恰好包含19个字符,程序也会终止。这种情况下,fgets()函数读取19个字符以后停止读入,所以下次调用时该函数将从行尾的换行符开始。这个换行符将成为读入的第一个字符,于是循环被终止。所以,尽管程序在本例中的输入情况下可以正常工作,但并非所有情况下都可以正确执行。应该使用一个大的足够容纳整行的存储数组,或者简单地每次只读入一个字符。

您也许会感到奇怪,为会么程序没有在键入第二行的前19个字符后立刻将其打印出来?这是由于有屏幕缓冲区存在。直到遇到了换行符时,才把第二行发送到屏幕上。

13.4.3  注释:gets()函数和fgets()函数

因为fgets()函数可以防止存储溢出,所以对于严格的编程来说,它是一个更好的选择。由于它将换行符读入到字符串,而puts()函数会在输出中追加一个换行符,所以fgets()函数应该和fputs()而不是puts()一起使用。否则,输入时有一个换行符而在输出时却变成两个。

前边讨论的6个I/O函数已经足够让您进行文件读写了。到目前为止,我们还只是使用它们进行顺序访问,即按顺序处理文件内容。接下来,我们将学习随机存取,也就是说,以任何需要的顺序访问文件内容。

转载于:https://my.oschina.net/idreamo/blog/835212

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值