• delphi pchar char byte string转换问题


    delphi pchar char byte string转换问题
    注:Delphi中的Char,PChar,PByte,Byte,String的相互转换,您是不是也遇到过,为此头疼过吗?你要是明白了他们的原理就会轻松了。

    话题064840的标题是: Q:关于PChar的用法 (200分)
    分类:非技术问题 PTiger (1998-10-19 18:33:00)
    我要从tPing.ini中读取Host段中的Address键值,但是读不出。
    1、首先往tPing.ini中写数据
    host := '8.8.8.8';
    WritePrivateProfileString(
    'Host', 'Address',
    PChar(host), 'tPing.ini');
    发现C:\WINDOWS\tPing.ini文件中已成功写入如下内容:
    [Host]
    Address=8.8.8.8
    2、读取数据
    var
    pAddress: PChar;
    str: String;
    acAddress: array[0..20] of Char;

    GetPrivateProfileString(
    'Host', 'Address', '127.0.0.1',
    pAddress, //这里改为PChar(str)也不行,用acAddress可以
    20, 'tPing.ini');
    但用就acAddress可以,不知为何?请问PChar与Char数组、String的用
    法有何区别?如果用PChar和String,分别如何实现?
    请赐教!先说谢了!
     
    tqz (1998-10-19 18:38:00)
    你这里的pAddress还没有分配内存呢!
    在GetPrivateProfileString前面加入:
    pAddress:=StrAlloc(20);
    使用完pAddress之后要释放掉:
    StrDispose(pAddress );
     
    曹晓钢 (1998-10-19 18:46:00)
    或许这是你想要的:
    var INI:TINIFile;

    begin
    INI:=TiNIFile.create('c:\tPing.ini');
    INI.ReadString('HOST','Address','0.0.0.0');

    定义是:
    function ReadString(const Section, Ident, Default: string): string;
    procedure WriteString(const Section, Ident, Value: string);
     
    dwwang (1998-10-19 18:49:00)
    PChar是指针,这一点上与C相同,因此你要使用(写)
    它,必须事先申请内存.你的程序直接用pchar,
    没有申请内存,因此肯定不行;相反,char数组是可以的.

    pchar与char数组可以直接转换,例如:你的程序里先写:
    pAddress:=@acaddress,然后再使用pAddress就可以成功了.
    或者用tqz的方法直接分配内存是一样的.

    StrPas和StrPCopy可以用来转换pchar与string,
    在你的程序里,读出数据后,用str:=strpas(pAddress)
    转换就可以了.
     
    O_O (1998-10-20 0:59:00)
    不知你用的Delphi是多少版本,2.0以上,将str定义为AnsiString,则可用pchar转换
     
    柳五公子 (1998-10-22 14:17:00)
    1. String是Pascal使用的字符串格式.它分为ShortString,
    WideString和AnsiString,String缺省为AnsiString.
    ShortString的最大长度为255个字符.
    AnsiString 的最大长度为2^31个字符.
    WideString 的最大长度为2^30个字符.
    AnsiString和WideString的区别在于字符集的不同.
    AnsiString对应于AnsiChar,WideString对应于WideChar.
    具体你可以参考Delphi Help中String Type帮助.

    2. PChar是Delphi为了和C语言的字符串类型(char *)兼容,
    以便调用Windows API而建立的数据类型.所以pchar实际是
    一个指针.一般使用方法是:
    pchar eg1;
    GetMem(eg1,Size); //你程序中出错就是因为没有为它分配内存
    ...
    FreeMem(eg1,Size);
    你还可以用以下方法;
    eg2 :array[0..Size] of char;
    然后可以把eg2看作pchar来用,且它已预先分配了内存.
    要注意的是定义eg2的字符数组下界必须是0 !否则将会出现错误.

    3. 在Delphi 1.0中的String和PChar的相互转换为:
    function StrPas(str :pchar):string;
    function StrPCopy(Dest:Pchar;Source:string):pchar;
    在Delphi 2.0和更高版本中的String和PChar的相互转换很简单:
    String ->Pchar: pch :=Pchar(str) ;
    Pchar ->String: str :=pch;

    4. String和pchar的内存实现方法略有不同(虽然他们实际上都是指针),
    所以你的例程中不能用pchar(str)来将返回值强制放入str中,而要首先
    用一个pchar型变量获得返回值(首先需为其分配内存),然后用
    str:=pAddress转换为string型放入str中.
    ###
     
    aimingoo (1998-10-23 8:05:00)
    天啊!!这个问题居然还没有收场???我本来这些天不打算在这儿回答问
    题,因为我在做我的MainPage,更糟糕的是,我的系统受到网络Hacker攻击,
    Format C:了。忙于整理系统的时候,还是被这200分给吸引了,毕竟,有银
    子可拿是无比爽快的事啊!

    ======================================
    1. 如果你的确可以用 acAddress: array[0..20] of Char;来传参数,那
    么就可以肯定,你没有为pChar分配内存。
    2. GetPrivateProfileString()的第四个参数是lpReturnedString,用于
    返回结果串。如果你没有给这个LPTSTR(Delphi中用pChar)分配内存,则返
    回为空,如果分配内存不足,将导致结果串不全。
    3. 问题是为什么呢?pChar的定义只是一个Pointer!!这意味着,除一个地
    址外,pChar本身不用于存放任何东西,也不存放字符串。要不你用sizeof(pChar)
    看看就明白了。那可只有4个byte呀!!

    4. 那么,pChar的字符串在那儿呢?它事实上被存放在以pChar指向的一个
    不定长内存块中。以#0为这个串的结束标志。如果没有特殊指定,Windows
    只在找到#0时就认为串结束,而不会如得到一个你所期望的字符串。

    5. 我们致少有以下三种解决方法:
    (1)在使用pAddress前分配内存,使用后释放内存。
    StrSize := 20;
    GetMem(pAddress,StrSize);
    ... //GetPrivateProfileString()调用
    FreeMem(pAddress,StrSize);
    (2)使用字符数组
    const StrSize = 20;
    var pAddress : pChar;
    chrArr : Array [0..StrSize] of Char;
    begin
    ...
    pAddress := @chrArr;
    ... //GetPrivateProfileString()调用
    end; //这种用法中,Delphi会自动释放掉chrArr所用内存
    (3) 直接使用字符串
    在Delphi 3及以上版本中,支持Huge String,你可以直接将String
    用成pChar(D2是否可以,我没有试过)。但是,你也要先给String指定一个长度。如下:
    var sAddress : String;
    StrSize : Integer;
    begin
    StrSize := 20;
    SetLength(sAddress,StrSize);
    GetPrivateProfileString('Host', 'Address', '127.0.0.1',
    pChar(sAddress), StrSize, 'tPing.ini');
    end;

    6. 关于建议:
    在上述三种方法中,第一种最安全,第三种是最方便的(因为你可以有一个
    动态的buffer,并且,可以象String一样方便的用它),我推荐使用第三种方法。
    WritePrivateProfileString()中的使用同上。但如果你采用第三种方法,
    则只需要将字符串写到Host串中,用pChar(Host)作为入口参数就成了。不需要
    再用SetLength()来指定串长。
    使用第三种方法如果编译时提示字符串类型转换错误,则是因为你没有将"Huge
    String"编译选项打开,可使用{$H+}编译符指定,或设置Project的Option


    ------------------------------------------

    在delphi中Char,PChar,PByte,Byte,String的相互转换示例:

    var
    s:string;
    pc:pchar;
    pb:pbyte;
    ac:array[1..100] of char;
    ab:array[1..100] of byte;
    i:integer;
    begin
    s:='this is a test';
    pc:=pchar(s); //string->pchar
    pb:=pbyte(pc); //pchar->pbyte
    for i:=1 to length(s) do
    begin
    ac[i]:=s[i]; //string->arrary of char
    ab[i]:=byte(s[i]); //string->arrary of byte
    end;

    s:=pc; //pchar->string
    s:=string(pb); //pbyte->string
    s:=c; //arrary of char->string;

    end;
    ------------------------------------------------------

    barton:

    虽然这个问题很简单,但其实很不人并不完全清楚。

    1.ShortString最大长度是由程序员指定的,但最多255个字符是不错。问题
    是Delphi在处理时有很大不同。ShortString可以用Str[0]取字符串长。在
    申请局部变量或者传递参数时ShorString在堆栈段分配空间,而其它类型的
    串是在堆中;如:MyStr: string[48];在堆栈段分配52字节空间存放一个短
    串。

    2.String分配和释放由Delphi去优化,你不用关心是否会造成内存泄漏。在每
    一个String变量前都有详细的RTTI去管理它。AnsiString和WideString其实
    和String在使用时是一样的,因为Delphi并未为AnsiString和WideString建
    立特殊的函数。传递参数时是一个地址。例如将流中的数据读到一个String
    中,应该按下列方式操作:
    SetLength(Result, Count); //相当于分配空间
    Stream.Read(Result[1], Count); //读数据到串

    3.PChar类型纯粹为兼容C和WindowsAPI而设,使用非常麻烦。
    APChar := StrAlloc(n); -- 分配空间
    StrDispose(APChar); -- 释放空间
    当然是以地址来传递的。
     

  • 相关阅读:
    MySQL事务处理
    MySQL触发器
    MySQL游标
    MySQL存储过程
    MySQL视图
    MySQL创建和操纵表
    Java异常体系结构以及异常处理机制、自定义异常
    Java的面向对象和抽象类、接口、内部类以及OOP实战
    Java数组声明创建和使用以及多维数组、Arrays类、稀疏数组
    Java通过循环结构和switch实现简易计算器
  • 原文地址:https://www.cnblogs.com/zhangzhifeng/p/2260483.html
Copyright © 2020-2023  润新知