请高手解说——高程之文件操作例题::莫名其妙~~

tjjmmtds 2003-08-24 02:31:34
可能是语文没学好了:(
看了半天下面的这段描述,再结合程序看看,还是不明白,这段文字要求是什么?题意是什么意思??
什么“合并”“恢复”“原始文件”的一大堆,又有什么结构的……我倒~~
哪位高手给偶解说一下题目的意思啊?——用通俗易懂的话来表白一下。。。
再告诉我这段程序运行时,我需要做哪些哪些事情(步骤)?

另外,我在程序中注释中有个关于类型转换的疑问(见下),既然sizeof是无符号型的,我把它强制转成long型为何不行啊?


---------
下面的程序从合并文件中恢复出其中一个或全部原始文件。所有文件都以二进制方式处理。存放顺序是:先逐个顺序存放各原始文件,然后顺序存放各原始文件的控制信息:文件名、文件长度和其在合并文件中的起始位置(偏移量),控制信息的格式如FileInfo结构,在合并文件的最后存放一个特殊的FileInfo结构作为合并文件的结束标记:FileInfo EndFlag={"CombinedFile",0,_offset};
其中_offset是第一个原始文件的控制信息在合并文件中的起始位置(偏移量)。
本程序的运行格式:
程序名 <合并文件名> [<原始文件名>]
这是用命令行参数的运行方式。如果不指定<原始文件名>,此程序将默认恢复合并文件中的所有原始文件;如果运行是没有输入命令行参数,则程序会提示输入<合并文件名>。

#include <stdio.h>
#include <string.h>

typedef struct
{
char fname[256];
long length;
long offset;
}FileInfo;

void copyfile(FILE *fin,FILE *fout,int fsiz)
{
char buf[1024];
int siz=1024;
while(fsiz!=0)
{
if (siz>fsiz)siz=fsiz;
fread(buf,1,siz,fin);
fwrite(buf,1,siz,fout);
fsiz=fsiz-siz;
}
}

int dofile (FILE *fin,FileInfo *inp)
{
long offset;
FILE *fout;
if((fout=fopen(inp->fname,"wb"))==NULL)
{
printf("创建文件错误:%s\n",inp->fname);
return 1;
}
offset=ftell(fin);
fseek(fin,inp->offset,SEEK_SET);
copyfile(fin,fout,inp->length);
fclose(fout);
printf("\n---文件名:%s\n文件长:%ld.\n",inp->fname,inp->length);
fseek(fin,offset,SEEK_SET);
return 0;
}

int main (int argc,char *argv[])
{
FileInfo finfo;
char fname[256];
FILE *fcmbn;
if(argc<2)
{
printf("输入合并文件名:");
scanf("%s",fname);
}
else
strcpy(fname,argv[1]);
fcmbn=fopen(fname,"rb");
if(fcmbn==NULL)
{
printf("文件打开错误:%s\n",fname);
return 1;
}
fseek(fcmbn,-sizeof(FileInfo),SEEK_END);/*改为fseek(fcmbn,-(long*)(sizeof(FileInfo)),SEEK_END);为何不行?*/
fread(&finfo,1,sizeof(FileInfo),fcmbn);
if(finfo.length!=0||strcmp(finfo.fname,"CombinedFile"))
{
printf("指定的文件不是合法的合并文件。\n");
fclose(fcmbn);
return 2;
}
fseek(fcmbn,finfo.offset,SEEK_SET);
for(;;)
{
fread(&finfo,1,sizeof(FileInfo),fcmbn);
if(finfo.length==0)break;
if(argc>2&&strcmp(finfo.fname,argv[2]))continue;
if(dofile(fcmbn,&finfo)!=0)break;
}
fclose(fcmbn);
return 0;
}
...全文
151 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
pengzhenwanli 2003-08-25
  • 打赏
  • 举报
回复
#include <stdio.h>
#include <string.h>
//我想数据的定义,和copyfile函数,不用注释。
typedef struct
{
char fname[256];
long length;
long offset;
}FileInfo;
void copyfile(FILE *fin,FILE *fout,int fsiz)
{
char buf[1024];
int siz=1024;
while(fsiz!=0)
{
if (siz>fsiz)siz=fsiz;
fread(buf,1,siz,fin);
fwrite(buf,1,siz,fout);
fsiz=fsiz-siz;
}
}

int dofile (FILE *fin,FileInfo *inp)
{
long offset;
FILE *fout;
if((fout=fopen(inp->fname,"wb"))==NULL)
{
printf("创建文件错误:%s\n",inp->fname);
return 1;
}
offset=ftell(fin);//保存目前的偏移量
fseek(fin,inp->offset,SEEK_SET);//移动到所要恢复文件的起始位置
copyfile(fin,fout,inp->length);//复制文件
fclose(fout);
printf("\n---文件名:%s\n文件长:%ld.\n",inp->fname,inp->length);
fseek(fin,offset,SEEK_SET);//恢复原来的文件位置指针(偏移量)
return 0;
}
/*******************************************************
*下面说说我对这个程序的理解。
*合并文件,就是你要处理的文件。
*原始文件,就是产生合并文件的文件。合并文件内容由
*一个一个原始文件和他们的控制信息组成。这个合并文
*件中存储了原来的文件的信息。如果你想要原来的文件,
*就叫做恢复原始文件。从合并文件的控制信息读出你想
*要恢复的文件信息(如果在命令行中指定)。
*关于命令行的解释:
*命令行的参数
*比如说这个程序的名字叫做 restorefile.exe
*合并文件名字叫做combinefile.dat
*则运行的时候这样输入 restorefile combinefile.dat
*第三个参数先忽略。你看看会产生什么文件?
*这个程序应该给出了示例文件,也就是我叫做
*combinefile.dat的文件。如果没有需要你先写一个。这样
*才比较好理解。这个程序应该不是你写的,不然你不会
*不理解?写合并文件应该有个程序。这比较麻烦,你自
*己写出来,应该会对这个程序有比较深刻的理解。
*不知我上面和下面的解释你满不满意?
*我这两天在研究C++的STL的实现,比较忙。要不是看在
*好几天没有给你解释问题的分上,对于这么复杂的程序,
*我一般不会看。今天给你忙了接近一个小时。
*******************************************************/
int main (int argc,char *argv[])
{
FileInfo finfo;
char fname[256];
FILE *fcmbn;
if(argc<2)
{
printf("输入合并文件名:");
scanf("%s",fname);
}
else
strcpy(fname,argv[1]);
fcmbn=fopen(fname,"rb");
if(fcmbn==NULL)
{
printf("文件打开错误:%s\n",fname);
return 1;
}
fseek(fcmbn,-sizeof(FileInfo),SEEK_END);/*改为fseek(fcmbn,-(long*)(sizeof(FileInfo)),SEEK_END);为何不行?*/
//怎么会行?在编译器看来此处的参数就是long类型的,如果你不使用强制类型转换,是根本不可能由(long*)转换到long的
//读取控制信息。
fread(&finfo,1,sizeof(FileInfo),fcmbn);

if(finfo.length!=0||strcmp(finfo.fname,"CombinedFile"))
{
printf("指定的文件不是合法的合并文件。\n");
fclose(fcmbn);
return 2;
}
//offset是第一个原始文件的控制信息在合并文件中的起始位置(偏移量)。
//从读取第一个文件控制信息开始
fseek(fcmbn,finfo.offset,SEEK_SET);
//下面这个循环是逐个读取文件的控制信息的,找到所匹配的。
//如果没有指定指定恢复文件的名字,则恢复所有的原始文件。
for(;;)
{
//从第一个控制信息开始
fread(&finfo,1,sizeof(FileInfo),fcmbn);
//如果没有合并文件的控制信息或者是读到了控制信息,退出循环
//这个地方我认为有毛病,如果文件是空的,也就是没有任何信息,仅仅有文件名,
//这样的话,应该恢复有文件名的空文件。但是这里,并不恢复。
if(finfo.length==0)break;
// 如果指定了想要恢复的原文件的信息(在argv的第三个位置),则查找文件信息。
if(argc>2&&strcmp(finfo.fname,argv[2]))continue;
//如果出错,则退出。
//但是从上面的dofile函数看来并没有控制出错处理!
if(dofile(fcmbn,&finfo)!=0)break;

}
fclose(fcmbn);
return 0;

}
pengzhenwanli 2003-08-25
  • 打赏
  • 举报
回复
先说一下吧,不是关于问题的。
对于你的提问,我浑身汗。感到很惭愧,就我这水平,还敢回答高程的问题?我的编程水平就是勉强过了计算机2级。我的胡说八道还有人听。
fastzch 2003-08-25
  • 打赏
  • 举报
回复
还是有一定的难度的,不然也不会是高程的题目。

祝你PASS。
huylghost 2003-08-25
  • 打赏
  • 举报
回复
mark
积木 2003-08-25
  • 打赏
  • 举报
回复
zzzzzzz 才睡醒
tjjmmtds 2003-08-25
  • 打赏
  • 举报
回复
哇这么详细……偶像!我崇拜你!
我……我……痛哭流涕……
tjjmmtds 2003-08-24
  • 打赏
  • 举报
回复
hellobcb:
禁止做广告!!!
---
咦,周末大家是不是都泡mm去了??怎么没人回答了??
hellobcb 2003-08-24
  • 打赏
  • 举报
回复
参考http://expert.csdn.net/Expert/topic/2167/2167108.xml?temp=2.936953E-02
tjjmmtds 2003-08-24
  • 打赏
  • 举报
回复
如上所述,我最大的疑问是不明白题目的意思……
对于三井的解释还是…… …… ……
tjjmmtds 2003-08-24
  • 打赏
  • 举报
回复
to goodboy1881三井石油:
你解说的偶有点不懂哦。可能还有些误会——你认为我是不理解文件函数干什么用的。对吧?look...
首先,你解说的那些文件函数不用解释了,偶知道这几个函数的用法:)
其次,你说建立一个新文件,把源文件读出来拷过去——这不叫做“复制”吗??怎么叫“合并”了呢?我认为合并应该是,a文件有内容,b文件也有,然后把两个文件的东西都读出来写到某个文件里,才叫“合并”。
如果说这样的话,那实际需要三个文件:abc。把a读出来写到c上,再读b的写到c上;在写完a的时候加个文件信息FileInfo,这样才行。
----
以上是我的理解哦,可能有些乱乱的,请原谅。
----
另外,我在程序中注释中有个关于类型转换的疑问(见下),既然sizeof是无符号型的,我把它强制转成long型为何不行啊?
kbsoft 2003-08-24
  • 打赏
  • 举报
回复
文件操作我都忘了 :-(
积木 2003-08-24
  • 打赏
  • 举报
回复
看看源程序吧
int main (int argc,char *argv[])
{
FileInfo finfo;
char fname[256];
FILE *fcmbn;

/*以上是定义部分*/


if(argc<2)
{
printf("输入合并文件名:");
scanf("%s",fname);
}
else
strcpy(fname,argv[1]);


/*这个是给文件名fname赋值*/


fcmbn=fopen(fname,"rb");
if(fcmbn==NULL)
{
printf("文件打开错误:%s\n",fname);
return 1;
}

/*打开文件以二进制唯读的方式*/

fseek(fcmbn,-sizeof(FileInfo),SEEK_END);

/*改为fseek(fcmbn,-(long*)(sizeof(FileInfo)),SEEK_END);为何不行?*/

/*fseek本来就要求一个long型来指定偏移量的,它不需要long* 懂没?*/

fread(&finfo,1,sizeof(FileInfo),fcmbn);

/*然后是读取文件结构信息;*/
if(finfo.length!=0||strcmp(finfo.fname,"CombinedFile"))
{
printf("指定的文件不是合法的合并文件。\n");
fclose(fcmbn);
return 2;
}
fseek(fcmbn,finfo.offset,SEEK_SET);



for(;;)
{
fread(&finfo,1,sizeof(FileInfo),fcmbn);
if(finfo.length==0)break;
if(argc>2&&strcmp(finfo.fname,argv[2]))continue;
if(dofile(fcmbn,&finfo)!=0)break;
}

/*以上的循环是合并文件的地方,其中
if(argc>2&&strcmp(finfo.fname,argv[2]))continue;
保证所有的文件都被复制*/
fclose(fcmbn);
return 0;
}
积木 2003-08-24
  • 打赏
  • 举报
回复
首先是题目的解释,我要合并文件,最简单的方法就是建立一个新的文件(目标文件)
然后把源文件一个个的读出来,写到目标文件中去,这样又一个好处,简单,但是
这样的合并后的文件就无法再分开了,因为它丧失了源文件的所有信息,例如文件的开始
结束,文件的大小,等等。所以这道题还要求你去在合并文件的时候记录源文件的信息
这道题也就这么简单
dddd8888 2003-08-24
  • 打赏
  • 举报
回复
long 是8个字节
long * 是4个字节
BorlandC 2003-08-24
  • 打赏
  • 举报
回复
/*改为fseek(fcmbn,-(long*)(sizeof(FileInfo)),SEEK_END);为何不行?*/


你这可不是转成long,而是long*了。

69,336

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧