标题:文本文件不能在VC++中正确执行吗?
只看楼主
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
得分:5 
你这个代码比较乱,是不是要把若干文件串接到目标文件中呀?初步看,问题跟"a+"模式很有关系,EOF未必存在于这种文件中,乱码在后面是不是?写到最后确定要终结时,记得补写一个EOF符号上去,确保安全,除非你不用EOF来检测文件结束。带+更新标志的文件读写,告一段落最好刷新一下缓冲区,比如你追加完一个文件,就强制写盘一次,到最后要显示ft,既然不想关闭文件再打开,就更要刷新一次缓存。这些保险措施,多写上去不会坏的,因为你未必知道那些库函数到底有做什么、没做什么,自己打保险好过依赖库函数的细节,要么你去仔细查过库函数参考手册这些函数的具体操作。

另外,你这种在循环中读文件名又检测打开是否失败的手段,最好戒了。你自己看,在后面的循环中,打开源文件失败exit()中断程序,原先打开了的ft没关闭被退出程序,那么那些数据会怎样?

写程序时,每一步都确保成功措施、调试过真的没问题,再进入下一步代码的编写。多个文件追加到同一个文件末尾,这样一气写下去,不如写一个关闭一个,反复打开和关闭,一个成功是一个,胜于半途某个不成功导致前功尽弃。你现在这样,到底哪出问题,最终还是要隔离各个步骤来排查,有什么区别呢。

[ 本帖最后由 TonyDeng 于 2011-12-26 18:17 编辑 ]

授人以渔,不授人以鱼。
2011-12-26 17:56
dreamofgod
Rank: 5Rank: 5
等 级:职业侠客
帖 子:194
专家分:341
注 册:2011-8-16
得分:0 
我没记错的话……
fopen("C:\Program Files\a.txt","a+")
要改成
fopen("C:\\Program Files\\a.txt","a+")

一个单片机就让我头疼不已~~~
2011-12-26 19:58
yeliming
Rank: 2
等 级:论坛游民
帖 子:23
专家分:23
注 册:2011-12-9
得分:0 
谢谢楼上的几位,尤其是Tony兄,真是一个热心的人,帮了我很多大忙!
2011-12-27 10:47
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
得分:0 


最后一句话的意思,是提醒程序员:如果你无法确定生成那个文件的程序使用的EOF值跟你现在读取程序的EOF值是相同的,那么用EOF来检测文件结束标志就存在风险。

[ 本帖最后由 TonyDeng 于 2011-12-27 11:59 编辑 ]

授人以渔,不授人以鱼。
2011-12-27 11:57
yeliming
Rank: 2
等 级:论坛游民
帖 子:23
专家分:23
注 册:2011-12-9
得分:0 
以下是引用TonyDeng在2011-12-26 17:56:04的发言:

"a+"模式很有关系,EOF未必存在于这种文件中,乱码在后面是不是?写到最后确定要终结时,记得补写一个EOF符号上去,确保安全,除非你不用EOF来检测文件结束。带+更新标志的文件读写,告一段落最好刷新一下缓冲区,比如你追加完一个文件,就强制写盘一次,到最后要显示ft,既然不想关闭文件再打开,就更要刷新一次缓存。这些保险措施,多写上去不会坏的,因为你未必知道那些库函数到底有做什么、没做什么,自己打保险好过依赖库函数的细节,要么你去仔细查过库函数参考手册这些函数的具体操作。

另外,你这种在循环中读文件名又检测打开是否失败的手段,最好戒了。你自己看,在后面的循环中,打开源文件失败exit()中断程序,原先打开了的ft没关闭被退出程序,那么那些数据会怎样?

写程序时,每一步都确保成功措施、调试过真的没问题,再进入下一步代码的编写。多个文件追加到同一个文件末尾,这样一气写下去,不如写一个关闭一个,反复打开和关闭,一个成功是一个,胜于半途某个不成功导致前功尽弃。你现在这样,到底哪出问题,最终还是要隔离各个步骤来排查,有什么区别呢。
个人总结:
1.“a+”模式确定是有EOF的,二进制模式没有这个符号。但是VC好像不认识CNTL_Z,怎么办?
2. 手动加EOF标志和更新缓冲,这两个个习惯我还真的一直没有,需要好好学习。
3. 好像尽量不要中途用exit退出,是不是有这个意思
4. while后面加分号,我都已经错误成习惯了,哎,这种错误还很难发现。
5. EOF不算char,之前学过的,但后面就忘了前面。
2011-12-27 11:58
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
得分:0 


这是对你使用getc()和putc()读写文件的一个提醒

授人以渔,不授人以鱼。
2011-12-27 12:02
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
得分:0 
回复 15楼 yeliming
1.a+模式是难以把握每次打开文件写操作定位到文件尾追加的时候,是否会覆盖文件中原先存在的EOF,万一它在EOF后面写数据呢?请留意14楼的资料。
2.每次关闭文件fclose()之前,定位到文件尾,fputc(EOF)一次,打开追加时,确认写指针指向EOF覆盖它。
3.除非非可控崩溃,当你主动中断程序的时候,要确保把屁股擦干净,前面已打开的ft流记得关闭、动态申请的内存记得释放(这是C++析构机制的优势,C是没有的)。
4.如果你写一个fappend()函数,一次只追加一个文件,循环执行,那么你可以确保每次该函数失败都同时关闭文件,但现在这样很可能忘记前面有需要收拾的东西。
5.凡用getchar()类函数,都应声明int,因为它们返回int,而且是带符号的。这点在《C陷阱》之类的书中是经常强调的,早已宣布这类函数的名称有明显的误导性。
6.操作尽可能简单,避免反复擦写文件数据、指针来回移动,追加文件就一直添加,无需回头读,用a不用a+,写完了关闭再打开读,就稳妥得多。

[ 本帖最后由 TonyDeng 于 2011-12-27 12:24 编辑 ]

授人以渔,不授人以鱼。
2011-12-27 12:14
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
得分:0 
对检测输入结束,用你跟用户约定的结束标志来结束是最好的。字符,不妨约定#之类为结束标志,数值,约定0或-1等现实情形不会是合法值的数据为结束标志。契约胜于潜规则,用户未必懂得怎么按^Z,但看提示说输入-1结束这样的字眼总是知道的。

授人以渔,不授人以鱼。
2011-12-27 12:37
yeliming
Rank: 2
等 级:论坛游民
帖 子:23
专家分:23
注 册:2011-12-9
得分:0 
关于EOF,以我现在入门的水平,我觉得你讲的有点深奥。
我测试了一下,在我的系统上,如果我在最后putc一个EOF的话,会多出一个乱码出来。
而且在我目前的系统上,用“a+”是能正确的在后面添加内容的,也就是说追加的时候能覆盖原来最后的EOF。

我现在还没学到系统编程,也还没有做一个具体的项目,不过我觉得你讲的还是对的,如果真的做项目的话,约定一定会比潜规则好!

还发现一点,在我的系统上,以二进制模式打开,也是能够识别EOF的。

关于可移植性,以后再慢慢学吧,呵呵!

[ 本帖最后由 yeliming 于 2011-12-27 13:56 编辑 ]
2011-12-27 13:49
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
得分:0 
EOF是判定用,写进去,读出来时丢弃不用显示,不输出到屏幕上哪来的乱码,仅仅用作文件结束标志罢了。

授人以渔,不授人以鱼。
2011-12-27 13:54



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-358659-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.133772 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved