C Primer Plus 第13章 文件输入/输出 13.3 文件压缩程序

这个程序把一个文件中的数据有选择的复制到另一个文件中。它同时打开两个文件,对其中一个使用"r"模式打开,对另一个使用“w”模式打开。程序清单13.2通过只保留每3个字符中的第3个来压缩第1个文件中的内容。最后,它把压缩后的文本写入到第二个文件中。第二个文件的名称就是第一个文件名后加.red(代表reduced)而得到的。

使用命令行参数,同时打开多个文件,以及对文件名进行追加操作,这些通常都是相当有用的技术。

程序清单13.2  reducto.c程序

//reducto.c--把您的文件压缩为原来的三分之一!
#include <stdio.h>
#include <stdlib.h>    //调用exit()
#include <string.h>    //为strcpy()和strcat()函数提供原型
#define LEN 40

int main(int argc,char * argv[])
{
    FILE * in,* out;    // 声明两个FILE指针
    int ch;
    char name[LEN];     //用于存储输入的文件名
    int count=0;
    //检查命令行参数
    if(argc<2)
    {
        fprintf(stderr,"usage:%s filename\n",argv[0]);
        exit(1);
    }
    //实现输入
    if((in=fopen(argv[1],"r"))==NULL)
    {
        fprintf(stderr,"I couldn't open the file \"%s\"\n",argv[1]);
        exit(2);
    }
    //实现输出
    strcpy(name,argv[1]);  //把文件名复制到数组中
    strcat(name,".red");   //在文件名后添加.red
    if((out=fopen(name,"w"))==NULL)
    {
        fprintf(stderr,"Can't create output file.\n");
        exit(3);
    }
    //复制数据
    while((ch=getc(in))!=EOF)
        if(count++ % 3 ==0)
        putc(ch,out);  //打印每3个字符中的1个

    //收尾工作
    if(fclose(in)!=0 || fclose(out)!=0)
        fprintf(stderr,"Error in closing files\n");
    return 0;
}

可执行文件名为reducto。我们用它对包含下面这行内容的文件eddy进行操作:

So enen Eddy came oven ready.

命令如下:

erducto eddy

输出结果被写入文件名为eddy.red的文件中。程序不产生任何屏幕输出,但打开文件eddy.red会显示如下内容:

Send money

这个例子演示了多项编程技术,下面我们来看看其中一些。

除了需要一个文件指针作为第一个参数以外,fprintf()和printf()函数基本一致。我们使用stderr指针把错误消息发送到标准错误文件,这是一个标准的C惯例。

为了给输出文件构建一个新的文件名,程序使用strncpy()函数把名字edd复制到数组name中。参数LEN-5为.red后缀名和最后一个空字符保留下空间。如果argv[2]字符串比LEN-5还长,就不会有空字符被复制了,因此程序只有在这种情况下添加一个空字符。调用strncpy()后name中的第一个空字符在strcat()函数附加上.red的时候,被其中的句号(.)给覆盖了,从而产生了eddy.red。我们还检查程序是否成功打开了文件名为eddy.red的文件。这在某此环境下尤为重要,因为像strange.c.red这们的文件名是非法的。例如,在DOS环境下不能再为文件后缀添加后缀(适用于DOS的方法是用后缀.red替换任何已有的后缀,这样压缩版本strange.c变成strange.red。例如,可以使用strchr()函数来定位文件名中的句号,然后只复制字符串中句号前的部分)。

这个程序同时打开两个文件,因此我们声明了两个FILE指针。注意每个文件的打开和关闭都是独立的。同时可以打开的文件数目是有限的。这个限制取决于系统和实现;范围通常是10-20之间。可以使用同一个文件指针指向不同的文件,但前提是不能同时打开这些文件。

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值