免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12345
最近访问板块 发新帖
楼主: lixforalpha
打印 上一主题 下一主题

[C] c语言 关于文件的两个问题 [复制链接]

论坛徽章:
0
41 [报告]
发表于 2003-12-29 17:18 |只看该作者

c语言 关于文件的两个问题

感谢  老K wl820406 win_hate  
前天一大早起来,一照镜子,脸胖了@_@,仔细一看左脸肿了 到医院检查有坏牙要补牙,先消炎消肿之后再拍片,再根据情况是补还是拨   还好神经已经坏掉,倒还不痛
"情况1,如果把 c 定义为 char,则读文件有可能意外终止,如果其中包含 0xff 字符。
情况2,如果把 c 定义为 uchar,则陷入死循环。编译器应该有警告。
情况3,如果把 c 定义为 int 则一切正常。"

今天对上面几种情况一一测试:
   平台:win2k -tc  源文件:带有0xFF的11字节大小的fputc1.dat
代码:
#include "stdio.h"
int test(void)
{int n;
char c;
FILE *fp2,*fp3;
  if((fp2=fopen("f:\\tc\\fputc\\fputc1.dat","rb")==NULL) return 1;
  if((fp3=fopen("f:\\tc\\fputc\\fputc3.dat","wb")==NULL) return 1;
  while((c=fgetc(fp2))!=EOF) fputc(c,fp3);
fclose(fp2);
return 0;
}
main()
{
  if(test())
    {printf("File not sussfull create!\n";
     return 0;
    }
    else printf("File already sussfull create!\n";
}

情况1:  运行n次,也不会产生什么问题!但是如果改一下代码
while((c=fgetc(fp2))!=EOF) fputc(c,fp3);为while(!feof(fp2)) fputc(fgetc(fp2),fp3);一运行我还以为死机了呢,结果产生了一个180多M的文件如图2所示
写进入两个FF,能理解,但为什么只写了180多M剩下40多M,没有把的F盘写满呢?判断条件没有改变,程序运行中间怎么就停止不写了?

情况2:char c;定义为unsigned char c;
       while((c=fgetc(fp2))!=EOF) fputc(c,fp3);代码,程序铁定死掉 结果如图3
       while(!feof(fp2)) fputc(fgetc(fp2),fp3);代码,不会死掉  结果如图4
      
情况3: 使用int c;定义 注意运行结果图5与图1的差别,图5中把fput1.dat文件中的FF同时复制到fput3.dat文件中,而图1中使用char c;则没有把FF复制到fput3.dat中。难道文件已经存在的FF和文件本身后面的EOF不是一回事?还要再想想

char c001.gif (12.9 KB, 下载次数: 42)

char c001.gif

论坛徽章:
1
荣誉版主
日期:2011-11-23 16:44:17
42 [报告]
发表于 2003-12-29 17:32 |只看该作者

c语言 关于文件的两个问题

如果调用者判断,那么系统(stdio.h)提供了一个宏EOF(-1)来判断文件是否结束,然而这种机制只适合ASCII文件,对于二进制使用这个来判断可能导致失败。


unix下处理都是二进制
谁有时间的话,可以到windows或者其他的非unix系统测试一下

论坛徽章:
0
43 [报告]
发表于 2003-12-29 19:18 |只看该作者

c语言 关于文件的两个问题

[quote]原帖由 "蓝色键盘" 发表:
如果调用者判断,那么系统(stdio.h)提供了一个宏EOF(-1)来判断文件是否结束,然而这种机制只适合ASCII文件,对于二进制使用这个来判断可能导致失败。


unix下处理都是二进制
谁有时间的话,可以到windows或

论坛徽章:
1
荣誉版主
日期:2011-11-23 16:44:17
44 [报告]
发表于 2003-12-30 08:52 |只看该作者

c语言 关于文件的两个问题

我是在项目中总结的教训,对于二进制,尽量不用EOF判断,而是用系统提供的函数feof

论坛徽章:
0
45 [报告]
发表于 2003-12-30 11:10 |只看该作者

c语言 关于文件的两个问题

为什么要加上对于UNIX而言
只要是在计算机上跑,ASCII文件和二进制文件根本上都是一样的
只是你看待它的方法不同罢了。

对于二进制文件是否可以用EOF来判断
我还真不知道会不会失败,因为我进行二进制文件操作根本就没用过EOF,一直是用feof()的,之所以这么用,原因很简单,在学C程序设计的时候老师这样讲的。

或许是我不求甚解,一直也没深刻研究一下为什么对二进制文件一定要用feof而不能用EOF,但我想既然老师这样讲一定会有一定的道理,您说呢。

论坛徽章:
1
荣誉版主
日期:2011-11-23 16:44:17
46 [报告]
发表于 2003-12-30 11:40 |只看该作者

c语言 关于文件的两个问题

呵呵,要是追根到底的话,连ascii和二进制都没有,都是01呀!

在根本的话,也不是01,是高低电位。

开个玩笑~~~~

论坛徽章:
0
47 [报告]
发表于 2003-12-30 15:35 |只看该作者

c语言 关于文件的两个问题

谨以此献不辞劳苦给予详细解释的win_hate、flw、dadaball、aero、蓝色键盘等众多网友

            完美解答

论坛徽章:
0
48 [报告]
发表于 2008-07-25 23:34 |只看该作者

把代码改为以下就可以了

#include <stdio.h>
int copy()
{
FILE *fp1,*fp2;
int ch,flag;
if((fp1=fopen("f:\\tc\\fputc\\fputc.dat","rb"))==NULL) return 1;
if((fp2=fopen("f:\\tc\\fputc\\fputc1.dat","wb"))==NULL) return 1;
while(flag = (!feof(fp1)))
        {
                ch = fgetc(fp1);
                flag = (!feof(fp1));
                if( flag == 1) fputc(ch,fp2t);
    }
fclose(fp1);
fclose(fp2);
return 0;
}

main()
{if(copy()) printf("文件不能顺利打开!");
  else printf("文件顺利复制!");
}

至于原因

win_hate 回复于:2003-12-26 10:17:28

引用:原帖由 "aero"]楼上的,这个是为什么呢?详细解释一下吧。
发表:


比方说,你的文件长为10字节,然后你进行10次

c=fgetc(fp);

则此时已将文件全部读出,但系统并不知道这一点,只有再读一次才能发现。此时 feof (fp) 返回的是 false,也就是未到文件末尾。所以此时如果再次getc,得到的是 -1,也就是 EOF

假定文件长度为10:

rep 10  c=fgetc (fp); // 到尾了
while (!feof (fp))  // 条件为真啊!
{
     c = fgetc (fp); // 得到的是 -1,也就是 EOF
     fputc (c, fp); // 把 EOF 写到文件里头了!!
}

上面的 while 循环在第二次执行的时候停止,所以总是多出一个 EOF


已经说清楚了

[ 本帖最后由 Linuxwhite 于 2008-7-25 23:39 编辑 ]
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP