fwrite()函数和fread()函数

4.二进制I/O:fread()和fwrite()函数

举个例子:

    double num=1./3.;  
    fprintf("fp,"%f",num);  
这个%f可以要求为%.2f或者%.12f,读取文件没有办法恢复其完整的精度。总之,fprintf()函数以一种可能改变数字值的方式将其转化为字符串。

最精确和一致的数字存储方式就是使用与程序所使用的相同位格式,比如一个double类型的值就应该存放在一个double大小的单元里面。如果把数据存储在一个使用与程序相同表示方法的文件中,就称数据以二进制形式存储,这中间没有数字形式到字符串形式的转化。实际上,所有数据都是以二进制的方式进行存储的,甚至连字符也都是使用二进制表示来存储的额。然而,如果文件中的全部数据都以字符编码的形式被解读,那么该文件包含文本数据;如果这些数据的部分或者全部以二进制的数字数据被解读,就称文件包含二进制数据,机器语言指令数据也是二进制文件。


5.size_t fwrite()函数

原型:

size_t fwrite(const void * restrict ptr,size_t size,size_t nmemb,FILE * restrict fp);

fwrite()将二进制数据写进文件。size_t是sizeof运算符返回的类型(通常是unsigned int 类型)。指针ptr是要写入的数据块的地址,size表示要写入的数据块的大小(单位为字节),nmemb表示数据块数目,fp指定要写入的文件。比如要保存一个256字节的数据对象(以数组为例):

    char buffer[256];  
    fwrite(buffer,256,1,fp);  
这样将一块256字节的数据块从缓冲区写入到文件;

也可以这样:

    double earnings[10];  
    fwrite(earnings,sizeof(double),10,fp);  
这样将earning里面的数据分成10块,每块都是double大小,写入文件。

注意:关于const void * restrict ptr,fwrite()的第一个参数不是固定的类型,比如可以使用字符型的buffer数组指针,可以使用double指针类型的earnings。

fwrite()函数返回成功写入的项目数。正常情况下,这个返回数应该和nmemb大小相等,不过要是写入发生错误的时候,可能这个返回数会小于nmemb的值。


6.size_t fread()函数

原型:


size_t fread(const void *restrict ptr,size_t size,size_t nmemb,FILE * restrict fp);  

prt为读取文件数据的内存存储地址,fp为指定要读取的文件,要恢复之前保存的包含10个double数的数组,这个时候可以使用下面代码:

 double earnings[10];  
 fread(earnings,sizeof(double),10,fp);  

下面是一个fwrite()函数和fread()函数的例子:

通常我们要实现一些目的,比如:把一系列文件的内容追加到另一些文件的结尾。可以通过交互式将文件信息传到程序中去。

通过以下几个步骤我们将实现目的:

1.请求一个目的文件名,并打开这个文件

2.使用一个循环来请求源文件

3.依次以读取模式打开每一个源文件,同时把它们的内容追加到目的文件

如何打开一个目的文件:

1.以追加模式打开最后一个命令行文件

2.不能成功就退出

3.为这个文件创建一个1024字节的缓冲区

4.如果不能创建就退出

文件复制步骤:

1.如果该文件与目的文件相同,就跳到下一个文件

2.如果不能以读取模式打开,就跳到下一个文件

3.把该文件的内容添加到目的文件中


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BUFSIZE 1024
#define SLEN 81

void append(FILE *source, FILE *dest);
int main(void)
{
    FILE *fa, *fs;        //fa指向追加的目的文件,fs指向源文件
    int files = 0;        //追加文件的个数
    char file_app[SLEN];//被追加文件的名称
    char file_sou[SLEN];//源文件名称
    puts("输入目的文件名:");
    gets(file_app);
    if ((fa = fopen(file_app, "a")) == NULL)
    {
        fprintf(stderr, "不能打开文件 %s\n", file_app);
        exit(2);
    }
    if (setvbuf(fa, NULL, _IOFBF, BUFSIZE) != 0)                //int setvbuf(FILE * restrict fp,char * restrict buf,int mode,FILE * rescrit ),当buf值为NULL时,此处为目的文件自动创建一个缓冲区,此处完全缓冲,如果不能成功创建,那么程序将终止
    {
        fputs("不能创建输出缓冲区\n",stderr);
        exit(3);
    }
    puts("输入第一个源文件的名称(空行离开):");
    while (gets(file_sou) && file_sou[0] != '\0')
    {
        if (strcmp(file_sou, filr_app) == 0)                    //假如file_sou源文件和file_app目的文件一样,此处防止程序将文件追加到自身
            fputs("不能附加文件到自身\n", stderr);
        else if ((fs = fopen(file_sou), "r") == NULL)            //如果不能打开文件
            fprintf(stderr, "不能打开文件 %s\n", file_sou);
        else
        {
            if (setvbuf(fs, NULL, _IFFBF, BUFSIZE) != 0)        //如果创建fs源文件的缓冲区不成功
            {
                fputs("不能创建输入缓冲区\n", stderr);
                continue;
            }
            append(fs, fa);
            if (ferror(fs) != 0)        //读写错误
                fprintf(stderr, "读取文件%s错误\n",file_sou);
            if (ferror(fa) != 0)            //读写错误,ferror()调用成功返回0,不成功读写错误返回非零值
                fprintf(stderr, "写入文件%s错误\n", file_app);
            fclose(fs);
            files++;
            prinf("文件%s已添加\n", file_sou);
            puts("下一个文件(空行离开):");
        }
    }
    printf("%d文件附加完成\n", files);
    fclose(fa);
    return 0;
}

void append(FILE *files, FILE *dest)
{
    size_t bytes;
    static char temp[BUFSIZE];        //分配一次

    while ((bytes = fread(temp, sizeof(char), BUDSIZE, source)) > 0)
        fwrite(temp, sizeof(char), bytes, dest);
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值