CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
山寨机中的战斗机! 程序优化工程师到底对IT界有没有贡献
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  Delphi >  语言基础/算法/系统设计

TfileStream中的read函数参数疑惑?

楼主ThinkInDelphi(wwwwww)2005-10-17 10:06:10 在 Delphi / 语言基础/算法/系统设计 提问

该read函数说明:read(Var   BUF;Size:int64);  
  BUF代表缓冲区(始址??)SIZE为从某文件流中读取数据到缓冲区的字节数。  
  我有一STRING变量:S:setlength(s,20);  
  下为出错代码:  
  tfileStream.create(filename).read(s,10):编译能通过,但运行到该句后发生ACCESSViolation异常。  
  修改后:tfileStream.create(filename).read(pointer(s)^,10);运行正常??!!  
  请各位大侠不吝指教,谢谢了!! 问题点数:50、回复次数:18Top

1 楼zsjzwj(北极熊)回复于 2005-10-17 10:23:07 得分 0

function   Read(var   Buffer;   Count:   Longint):   Longint;   override;  
   
  property   Buffer:   PChar;  
   
  因为你的变量s是string类型,需要转换为CHAR类型才可以用Top

2 楼alexanda2000(书生活)回复于 2005-10-17 10:26:24 得分 0

tfileStream.create(filename).read(s[1],10);Top

3 楼ThinkInDelphi(wwwwww)回复于 2005-10-17 10:48:11 得分 0

谢谢zsjzwj的分析。他找到了问题所在,只是不详细:string默认是AnsiString,一个4字节的指针。PCHAR是一个NULL-TERMINATE类型(以#0结尾)的字符串。(应该和AnsiString一样是一个4字节的指针?)同样是指针,为何有区别?  
        感觉alexanda2000更进了一步,s[1]为字符串第一字符。但BUF一般是指针啊?我就是这个不理解?!Top

4 楼alexanda2000(书生活)回复于 2005-10-17 10:54:05 得分 0

string实际上就是指针,也是以#0结尾,只是它指向的不是第一个字符。S[1]才是它的字符开始的地方。Top

5 楼alexanda2000(书生活)回复于 2005-10-17 10:55:48 得分 0

tfileStream.create(filename).read(s,10)实际上将流的数据写入了字符串用来存储其它相关信息的地方,所以就会出错了。Top

6 楼ThinkInDelphi(wwwwww)回复于 2005-10-17 10:56:00 得分 0

另外我用“S^”来指定第一个字符,不用s[1],编译都有问题.为什么??(我以前的C语法在Delphi老是不管用!)类似C中:string   S;  
                                            printf(%c,*S)与printf(%c,S[0])一样的吧?Top

7 楼ThinkInDelphi(wwwwww)回复于 2005-10-17 11:01:01 得分 0

看一下read定义:  
  function   Read(var   Buffer;   Count:   Longint):   Longint;   override  
  BUffer显然是一个指针啊!  
  S[1]是个字符。这能对吗??Top

8 楼lyre(大头鬼)回复于 2005-10-17 11:04:31 得分 0

S[1]可以用,但最好用PChar(s)来取得首地址,切记要先使用SetLength给字符串分配空间,否则还是有可能访问非法地址。另外,Delphi的语法与C不一样,C当中数组和指针是一回事,但在Delphi中不是,更何况String类型并非数组。Top

9 楼ThinkInDelphi(wwwwww)回复于 2005-10-17 11:04:56 得分 0

注意pointer(s)^应该也表示S中第一个字符?或是其他?  
  另外tfileStream.create(filename).read(s[1],10);是不是能运行正常,我还没试过呢,明天给答案:-)Top

10 楼lyre(大头鬼)回复于 2005-10-17 11:05:58 得分 0

对于你的要求,最好自定义一个字符数组作为Buf:  
  var  
      Buf:   array[0..1023]   of   char;Top

11 楼ThinkInDelphi(wwwwww)回复于 2005-10-17 11:07:32 得分 0

s[1]是指针?????????!!!  
  头脑短路中........Top

12 楼ThinkInDelphi(wwwwww)回复于 2005-10-17 11:15:49 得分 0

S[1],s[1],s[1]...........  
  to     lyre:你的方法是对的,数组名是指针。那字符串名到底是不是指针??  
  “C当中数组和指针是一回事,但在Delphi中不是”说得具体点~~    
  Top

13 楼lyre(大头鬼)回复于 2005-10-17 12:34:22 得分 0

Delphi是强类型的语言,不像C中指针和数组可以通用,虽然实际上数组名作为一个变量来说,确实有一个对应的内存地址,而且你把它强制转换为指针后,访问的内容也是正确的。  
  Delphi中的字符串实际上是以前Pascal短字符串与C的以0结尾的字符串的一种综合体,也就是说,最前面有几个字节保存的是字符串的长度,然后是实际内容,最后又有一个结尾的0。Top

14 楼ThinkInDelphi(wwwwww)回复于 2005-10-17 12:48:59 得分 0

lyre说得没错,对于第二段内容我也了解。(第一段精彩!)  
  回到问题:  
  那s[1]是不是指针?  
  BUF指得是一个指针变量?  
  如果BUF是指针,那Pointer(S)^代表的是一个字符还是指针?[参数类型匹配吗?]  
  S^与Pointer(S)^的区别?(STRING指针与无类型指针我知道(都4字节),但不能替换使用,否则上面程序异常。难道这就是所谓“强类型”?)  
  Top

15 楼lyre(大头鬼)回复于 2005-10-17 14:48:24 得分 25

S[1]不是指针,而是指字符串的第1个字符。你注意read的定义:  
  read(Var   BUF;Size:int64);  
  其中的Buf是一个无类型参量,这种情况下调用时不限参数类型。另外Buf是作为var定义的,传递参数时是将参数的地址传进去的。(实际上无类型参数也只能用var来定义。)C语言这种情况下需要&符来取址,Delphi不需要。  
  read(s[1],   ..);         ==>传入S[1]的地址。因为String类型的第一个字符下标从1开始,所以S[1]的地址也正是字符串正文开始的地址;  
   
  S虽然实际上是个指针,但这是对Delphi而言的,在引用的时候Delphi会循着S指明的地址依次找到字符串长度、内容、结尾的0等;对用户而言它是一个语言内建的数据类型而不是指针,所以S^的写法是错误的。  
  如果你把S强行转化为指针,将Pointer(S)^作为参数传给Read的时候,它实际指向字符串开头的字符串长度所在位置,你往这里写东西,当然就破坏了字符串的结构了;Top

16 楼alexanda2000(书生活)回复于 2005-10-17 15:22:32 得分 25

lyre(大头鬼)已经解释得很清楚了,read(Var   BUF;Size:int64);中的buf是变参,read方法接收到的已经是buf的地址了,因此buf不需要传入指针变量。如果你真的传入一个指针,这个方法接收到的就是指针自身地址了,反而会出错。因此用s[1]作为buf的话,这个方法接收到的是s[1]的地址。  
   
  在Delphi中,数组不是指针,声明一个arr:array[0..12]   of   char,你看一下SizeOf(arr)就知道了。  
   
  PS:我觉得将Pointer(S)^作为参数传给read是可以的,因为Pointer(S)^表示了“S正文的内容”,它的地址应该和s[1]是一样的。Top

17 楼ThinkInDelphi(wwwwww)回复于 2005-10-19 12:32:18 得分 0

问题已经解决了。谢谢各位兄弟!!  
  分数将对半分给   lyre和   alexanda2000  
  另外   alexanda2000最后的回复是正确的,我已验证。原因我琢磨应该如下:  
  S作为一个“指针”来说,是一个指向STRING第一字符的指针,而不是指向长度值。  
  S作为一个字符串来说,S^不能用,即Delphi限制用户只能从s+1开始。  
  Pointer(S)^==s[1]  
  Top

18 楼alexanda2000(书生活)回复于 2005-10-19 14:55:08 得分 0

>>>S作为一个“指针”来说,是一个指向STRING第一字符的指针,而不是指向长度值。  
   
  错了,如果它真的指向第一个字符,就不用s[1]这么麻烦了。  
  《Delphi5   开发人员指南》中对字符串结构有比较详细的介绍。Top

相关问题

  • 函数参数的疑惑
  • 疑惑:关于使用SqlParameter函数构造数据查询参数的问题。
  • biosdisk()函数参数
  • 函数和参数
  • 构造函数的疑惑
  • WSAAsyncSelect 函数参数问题
  • 传递函数做参数
  • 函数得参数问题
  • C++ 函数参数问题!
  • main函数参数问题

关键词

  • 指针
  • 字符
  • delphi
  • 内容
  • 语言
  • 数据
  • 字符串
  • 数组
  • tfilestream
  • 参数

得分解答快速导航

  • 帖主:ThinkInDelphi
  • lyre
  • alexanda2000

相关链接

  • Delphi类图书
  • Delphi类源码下载
  • Delphi控件下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
北京创新乐知广告有限公司 版权所有, 京 ICP 证 070598 号
世纪乐知(北京)网络技术有限公司 提供技术支持
Copyright © 2000-2008, CSDN.NET, All Rights Reserved
GongshangLogo