LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 1888|回复: 9

编写最简单的copy程序发现的问题

[复制链接]
发表于 2002-10-1 17:53:53 | 显示全部楼层 |阅读模式
最简单的copy程序就在现在大学里广泛使用的那一本谭浩强的教材中关于“文件”那一章节里。我发现运行该程序以后copy出来的新文件比原来的文件在末尾多了一个ascii代码为152的字符。这是怎么回事?
发表于 2002-10-3 15:09:31 | 显示全部楼层
???
不是每个人都学这个教材的,你写出来一下嘛
发表于 2002-10-5 18:27:02 | 显示全部楼层
指针问题,你检查一下有没有哪里用的不规范
 楼主| 发表于 2002-10-6 19:41:07 | 显示全部楼层
/*copy infile to outfile*/

#include"stdio.h"
#include"stdlib.h"

main()
{FILE *in,*out;
char infile[20],outfile[20];
printf("infile name: ");
scanf("%s",infile);
printf("outfile name: ");
scanf("%s",outfile);
if((in=fopen(infile,"r"))==NULL)     /*open files. If failed, quit.*/
  {printf("Cannot open infile\n.");
  exit(0);
  }
if((out=fopen(outfile,"w"))==NULL)
  {printf("Cannot open outfile.\n");
  exit(0);
  }
while(!feof(in))fputc(fgetc(in),out);
fclose(in);                           /*close files*/
fclose(out);
}                                     /*the end*/


infile:
hello

outfile:
hello

看起来infile和outfile内容一样,但是outfile实际上在末尾多了一个字符。
 楼主| 发表于 2002-10-16 23:17:08 | 显示全部楼层

问题就出在feof函数上,但是我没有办法解决。

我仔细翻看了相关的书籍,还做了一些实验,发现问题就出在feof函数上。这就要从这个函数的来历说起了。
    feof函数是为了解决判断文件是否结束而编写的。本来对于文本文件,用fgetc进行读写时如果遇到文件结束,就会返回-1。由于文本文件中ANCII码全部是大于-1的,但是如果在读写二进制文件的时候,就会有可能读入一个值为-1的数据,这样就造成了需要读入有用的数据却没有读入的情况。于是就有了feof这个函数。
    但是这样以来,如同上一个帖子所说的那样,就会在复制的目标文件末尾多产生一个-1,于是就有了我提出的问题。
    应该如何解决呢???
发表于 2002-10-17 08:54:59 | 显示全部楼层
/*copy infile to outfile*/

#include"stdio.h"
#include"stdlib.h"

main()
{FILE *in,*out;
int i;
char infile[20],outfile[20];
printf("infile name: ");
scanf("%s",infile);
printf("outfile name: ");
scanf("%s",outfile);
if((in=fopen(infile,"r"))==NULL) /*open files. If failed, quit.*/
{printf("Cannot open infile\n.");
exit(0);
}
if((out=fopen(outfile,"w"))==NULL)
{printf("Cannot open outfile.\n");
exit(0);
}
while(1)
{
i=fgetc(in);
if(feof(in)) break;
fputc(i,out);
}
fclose(in); /*close files*/
fclose(out);
} /*the end*/

讨论:
如果按照楼上的程序,在while循环判断时,这一句
fputc(fgetc(in),out);
已经进行了写操作。因此应该把上面的语句分解来解决。
呵呵,有些教科书本来作者就是抄来的代码,又没有亲自实验,于是出现了上面的情况。:-(
 楼主| 发表于 2002-10-17 09:58:59 | 显示全部楼层

多谢!能更加深入一些吗?

    多谢!
    不过我对这个while语句还是有一点不大明白,能不能再深入一点讲解一下?
    在楼上的程序中,有语句while(!feof(in))进行循环控制,即先判断再执行。既然对infile的指针in到了文件的结尾,判断语句中函数的返回值经过非运算以后就变成了0,那么循环就应该不会再执行下去了,即循环就已经结束了。可是在事实上为什么还会多进行一次写操作?难道while语句是边判断边执行的吗?还是这个宏函数feof有什么特别的地方呢?
发表于 2002-10-17 16:00:44 | 显示全部楼层
这么理解,当读到最后一个字节时,这时fputc(fgetc(in),out);语句正常执行,此时进行while(!feof(in))进行判断,由于是最后一个字节,判断的结果正确,继续下一次循环,这时执行fputc(fgetc(in),out);但此时已到文件尾,读文件失败!但仍然把失败结果写入out里!完毕后再进行while判断,此时为假,退出循环!但文件中已经写入多余的一个字符了。

解释的已经很清楚了,不再进行解释了。:-)
 楼主| 发表于 2002-10-17 16:19:52 | 显示全部楼层

原来如此,但是还是有一点需要特别解释——多谢!

多谢了,但是还是有一点需要特别解释。这个问题是:到底那一个函数使得文件指针发生了向文件尾端的移动——是不是fgetc,而且是使用以前就移动了?如果是的话,那么在读文件开头第一个字节的时候它就应该是指向一个空的值(NULL)?
发表于 2002-10-18 08:21:54 | 显示全部楼层
开头时,文件指针为0 。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表