中国IT动力,最新最全的IT技术教程
最新100篇 | 推荐100篇 | 专题100篇 | 排行榜 | 搜索 | 在线API文档
首 页 | 程序开发 | 操作系统 | 软件应用 | 图形图象 | 网络应用 | 精文荟萃 | 教育认证 | 硬件维护 | 未整理篇 | 站长教程
ASP JS PHP工程 ASP.NET 网站建设 UML J2EESUN .NET VC VB VFP 网络维护 数据库 DB2 SQL2000 Oracle Mysql
服务器 Win2000 Office C DreamWeaver FireWorks Flash PhotoShop 上网宝典 CorelDraw 协议大全 网络安全 微软认证
硬件维护  CPU  主板  硬盘  内存  显卡  显示器  键盘鼠标  声卡音箱  打印机  机箱电源  BIOS  网卡  C#  Java  Delphi  vs.net2005
  当前位置:> 程序开发 > 编程语言 > C/C++
请教一个c++读取文件的问题,急
作者:未知 时间:2005-09-13 19:28 出处:ChinaUnix.net 责编:chinaitpower
              摘要:请教一个c++读取文件的问题,急

在c++里
memset( buff , 0x00 , sizeof( buff ) ) ;
fp = fopen( "filename" , "r" ) ;
fread( buff , 1000 , 1 , fp ) ;
buff[strlen(buff)] = '\0' ;
log( buff ) ;(把buff printf出来)结果buff后面有乱码,怎么解决?
buff里面有很多行,包括换行符号的
unix下c没有问题

 飞灰橙 回复于:2004-04-25 17:32:21
buff[strlen(buff)] = '\0' ; 
这一句理解肯定有错误
strlen依靠buff中的'\0'来计算长度,
没有'\0'之前,肯定strlen算不出正确的值来

 llzh 回复于:2004-04-25 17:46:06
不好意思,实际程序里是
iBufflen = strlen( caBuff ) ;
caBuff[iBufflen] = '\0' ;

而且好象后面多出的字节刚好是文件的行数
比如有10行,就多出10 个乱字节
但是不是出现在没一行后面,而是在全部打出之后

 飞灰橙 回复于:2004-04-25 17:56:51
问题照旧
strlen怎么知道caBuff的长度呢?

 whyglinux 回复于:2004-04-25 18:32:11
请问楼主,你读取的文件大小是不是超过了 1000 字符?如果没有超过,你应该能得到正确的结果;如果文件大小超过了 1000 字符,你的处理就是错误的了。在这种情况下,应该根据实际读出的字符数决定字符串结束标志的位置。

// memset( buff , 0x00 , sizeof( buff ) ) ; // 这一句没有必要
fp = fopen( "filename" , "r" ) ;
size_t n;
// fread( buff , 1000 , 1 , fp ) ;
n = fread( buff , 1 , 1000-1 , fp );
// buff[strlen(buff)] = '\0' ;  // 这一句实际上不起任何作用,因为 strlen 函数就是根据字符串结束标志 '\0' 工作的,即 buff[strlen(buff)] 一定为 '\0'。
buff[n] = '\0'; // 设置字符串结束标志

 llzh 回复于:2004-04-25 19:31:07
cabuff 就是fread( "filename" , "r") l里面的buff 

没有超过1000字符
而且buff[strlen(buff)] = '\0' 实际上是没有用到的,上面说到过
至于fread( buff , 1 , 1000-1 , fp ); 和fread( buff , 1000 , 1 , fp ) ;只是返回的items的问题,我以前试过,没有多大区别
请问1000的限制是什么原因?我现在已经很迷惘,以前都是在unix下写程序

 llzh 回复于:2004-04-25 19:35:38
上面写错了
是fread( buff , 1, 1000,fp)里的buff就是caBuff

 llzh 回复于:2004-04-25 20:00:01
原文件:588字节
3001 1234 00001 001 1105081101101000004927 5.99 435 00
3001 1235 00001 001 1105081101101000004927 5.99 435 00
3001 1236 00001 001 1105081101101000004927 5.99 435 00
3001 1236 00001 001 1105081101101000004927 5.99 435 00
3001 1236 00001 001 1105081101101000004927 5.99 435 00
3001 1236 00001 001 1105081101101000004927 5.99 435 00
3001 1236 00001 001 1105081101101000004927 5.99 435 00
3001 1236 00001 001 1105081101101000004927 5.99 435 00
3001 1236 00001 001 1105081101101000004927 5.99 435 00
3001 1236 00001 001 1105081101101000004927 5.99 435 00

fread日志打出598字节
3001 1234 00001 001 1105081101101000004927 5.99 435 00
3001 1235 00001 001 1105081101101000004927 5.99 435 00
3001 1236 00001 001 1105081101101000004927 5.99 435 00
3001 1236 00001 001 1105081101101000004927 5.99 435 00
3001 1236 00001 001 1105081101101000004927 5.99 435 00
3001 1236 00001 001 1105081101101000004927 5.99 435 00
3001 1236 00001 001 1105081101101000004927 5.99 435 00
3001 1236 00001 001 1105081101101000004927 5.99 435 00
3001 1236 00001 001 1105081101101000004927 5.99 435 00
3001 1236 00001 001 1105081101101000004927 5.99 435 00 屯屯屯屯?

 whyglinux 回复于:2004-04-25 20:16:52
>> 而且buff[strlen(buff)] = '\0' 实际上是没有用到的,上面说到过 
你明明在上面写了 iBufflen = strlen( caBuff ) ; caBuff[iBufflen] = '\0' ; 这和 caBuff[strlen( caBuff ) ] = '\0' 有何区别?

>> 至于fread( buff , 1 , 1000 , fp ); 和fread( buff , 1000 , 1 , fp ) ;只是返回的items的问题,我以前试过,没有多大区别
它们的区别就是返回值不同。而你正是需要根据这个返回值判断到底 fread 从文件中实际上读取了多少字节的字符,然后根据这个字符数设置字符串的结束标志,就象我在上面写的内容一样。如果是这样,你看应该使用那一种形式的 fread ?你觉得没有区别,那是因为你没有用到 fread 的返回值。

其实我上面已经给出你程序了,你为什么不试试之后再说呢?

>> 请问1000的限制是什么原因?我现在已经很迷惘,以前都是在unix下写程序
你可能定义用来存放字符的 buff 的大小为 1000,即 char buff[1000]。这样,buff 中最多只能存放 1000 个字符,显然,如果你的文件超过了 1000 字符,只读一次是不够的,即使是你在 Unix 下写的程序。

 llzh 回复于:2004-04-25 21:00:58
size_t fread( void *buffer, size_t size, size_t count, FILE *stream );
我也试过你那种方式,比如n = fread( buff , 400 , 1 , fp ) ; 正确返回值n=0;在unix下编译运行,如果是fread( buff , 1 , 400, fp ) 则正确返回为所读出的长度,函数在两个系统应该没有区别,我看了msdn

开始的buff,我是动态产生的,根据文件的长度申请内存+1,应该是没有问题的
谢谢你的回答,我刚才又试了一下,还是一样,不知道是不是别的原因

 henngy 回复于:2004-04-26 09:51:45
晕撒,,,换read不就没有了吗?试试

 llzh 回复于:2004-04-26 12:55:56
一样的结果

现在我把它换成fgets,多取几次算了,至少结果是正确的

 hh942111 回复于:2004-04-26 13:24:48
如果buf是你在前面动态生成的话,你的这一句
>>memset( buff , 0x00 , sizeof( buff ) ) 
就有问题啊!这样的sizeof不能得到你想要的东西

 llzh 回复于:2004-04-26 13:53:40
不好意思,有些没有说清楚,当时写出来是有点忙,本来是:
先取到文件长度lFilelen ,
buff = ( char *)malloc( lFilelen + 1 ) ; 之后的判断就不写了
memset( buff , 0x00 , lFilelen + 1 ) ;
然后再使用buff

多谢各位大侠关照,不胜感激

 whyglinux 回复于:2004-04-27 13:17:49
>> 现在我把它换成fgets,多取几次算了,至少结果是正确的
楼主已经换用 fgets (可能写文件的时候还有 fputs)实现了要求,本来不想再说什么了。但是以前用 fread(应当还有 fwrite,虽然楼主没有向我们说明)的时候还没有得到正确的结果,其原因还没有解明,觉得有必要再提醒一下。

我在上面已经指出了使用 fread 正确读出文件内容到 buff 中的方式,其关键就是根据 fread 的返回值(即实际读取的字符数)来确定字符串结束标志 '\0' 在 buff 中的位置。本来希望对楼主有所启发,但是楼主却执着于根据文件的大小来确定写入文件的字符数(应该告诉而没有告诉我们),看来没有达到目的。

楼主给出的代码如下:
memset( buff , 0x00 , sizeof( buff ) ) ;
fp = fopen( "filename" , "r" ) ;
fread( buff , 1000 , 1 , fp ) ;
buff[strlen(buff)] = '\0' ;
log( buff ) ;

log 函数之前的问题我上面已经给解决了(再重复一遍:程序中的 memset 函数的使用没有任何必要性。楼主好像还是没有意识到这一点)显然,log 函数是把 buff 中的字符串写到一个文件中。楼主的程序之所以出问题,就在于在 log 函数内的处理错误:在写 buff 到文件中的时候,对于写入的字符数,用的是文件长度,而不是 buff 字符串的实际长度!如果改为:fwrite( buff, sizeof(char), [color=red:46797d3c2a]strlen(buff)[/color:46797d3c2a], fp );就能得到正确的结果了。

那么,原来的程序为什么在 Unix 执行正确而在 Windows 下执行就得不到正确结果呢?其原因在于 Unix 和 Windows 下文本文件对于换行符号的处理不同:Unix 在每一行尾用一个字符 '\n' 表示换行,而 Windows 用 '\r' 和 '\n' 两个字符表示换行;但是在用C/C++读取到内存之后,无论在哪个系统上,却都是转换成 '\n' 一个字符,由此导致在 Windows 下 fread 出的文件长度并不对应文件中的字符数(在Unix下不存在这一问题),所以不要根据文件长度确定文件中的字符数(根据文件大小判断所需要分配的存储空间大小还是可以的),应该使用字符串的实际长度。

楼主上面给出的结果分析也说明了这一点。
>> 而且好象后面多出的字节刚好是文件的行数
>> 比如有10行,就多出10 个乱字节
>> 但是不是出现在没一行后面,而是在全部打出之后

 llzh 回复于:2004-04-27 18:28:46
对!就是这个原因,我后来发现每一行后面有0D 0A两个字节,也就是楼上说的'\r','\n'。于是又改回用实际长度去读取,居然可以,虽然交差通过不过仍然不是很理解,怀疑原文件有问题。
现在听楼上一说,才明白其中原因,楼上严谨的态度让我佩服,再次谢谢

 aibitx 回复于:2004-05-07 00:44:03
楼主,你用
fp = fopen( "filename" , "r" ) ; 
fread( buff , 1000 , 1 , fp ) ;//fread是用于二进制文件的,用"r"是不
//是文本方式打开的?我的QQ是:21546640

 flw 回复于:2004-05-07 17:05:58
[quote:52ba451723="llzh"]buff[strlen(buff)] = '\0' ;[/quote:52ba451723]
脱了裤子放不出来屁。

比脱了裤子放屁还浪费。

 pheonix9463 回复于:2004-05-11 21:26:08
精灵王的水平真的很强,佩服佩服啊!!!

提倡大家都向你学习,学习你的求真的精神,呵呵

关闭本页
 
首页 | 投资与合作 | 服务条款 | 隐私政策 | 收藏本站 | 设为首页 | 新用户注册 | 免责声明 | 使用帮助
Copyright ©2005-2008 chinaitpower.com All rights reserved. www.chinaitpower.com 版权所有