var
  b:string;
  c:string[5];
begin
  b :='12345';
  copymemory(@c,pchar(b),5); 
  memo1.Lines.Add(c);
end;
它的内容为'2345**'.我的问题是怎么修改copymemory(@c,pchar(b),5)中@c这个地方,让上面的过程等于c:=b,
即c的内容为:c:='12345'.

解决方案 »

  1.   

    var
      b:string;
      c:string[5];
    begin
      b :='1234'#0;
      copymemory(Pointer(Integer(@c)+1),pchar(b),5);
      memo1.Lines.Add(c);
    end;
    string类似第一个字节存放的是引用计数
    另,如果c不是以#0结尾,会访问不属于它的内存.
      

  2.   

    大家帮帮忙啊,我还可以提供下面这个东西,让大家看看
    var
      a,b:string;
    begin
      b :='12345';
      SetLength(a,5);
      copymemory(pchar(a),pchar(b),5);
      memo1.Lines.Add(a);
    end;
    这个是成功的.所以我想看看如果先给定了string的长度,会怎么样,结果不行.
      

  3.   

    to  ysai:
      你做一下试验就知道了.我的问题不会出现“它的内容为'2345**'.”这个的,
    我之所以那样写,是因为我用showmessage调试,才会出现,所以你的解释是不通的。
      

  4.   

    如果你看不懂我的解释,我就不知道怎么跟你说了,呵呵~
    string与string[5]是不同的.如果你知道内部怎么实现的,你就不会有这样的问题了
      

  5.   

    不要用move,我就是要用copymemory,我要搞明白静态string它的指针是怎么指的。
      

  6.   

    呵呵
    这是概念混淆了string类型默认是AnsiString类型的
    string[5]这样的形式是ShortString类型的ShortString是Delphi 1.0中字符串的类型,在内存中,它就像是一个字符数组,在字符串的第0个元素中存放了字符串的长度,紧跟在后的字符才是字符串本身。看到这明白了吗?他的实际长度比字符串的长度多一位所以你上面的总是显示2345你改成这样再看看var
      b:string;
      c:string[6];//注意这里长度要变啦
    begin
      b :='12345';
      copymemory(@c[1],pchar(b),5);//这里也别从第0位copy啦
      

  7.   

    String的结构
    String[0]是字符串的长度
    String[1]开始才是内容.
    剩下的你自己搞定吧.
      

  8.   

    to chijingde:
    好像还不是这么简单,你试试这个
    var
      b:string;
      c:string[6];//注意这里长度要变啦
    begin
      b :='1234567890';
      copymemory(@c[3],pchar(b),3);//这里也别从第0位copy啦
      memo1.Lines.Add(b);
    end;
      

  9.   

    memo1.Lines.Add(b);
    b... ...-_-!
      

  10.   

    to ysai:
    var
      b:string;
      c:string[5];
    begin
      b :='1234'#0;
      self.Caption:=inttostr(length(b));//加上这一句,你的程序就显示不出来
      copymemory(Pointer(Integer(@c)+1),pchar(b),5);
      memo1.Lines.Add(c);
    end;
    这个怎么解释呢?
      

  11.   

    to chijingde
    你的程序和上面那位也一样;
    var
      b:string;
      c:string[6];//注意这里长度要变啦
    begin
      b :='12345';
      self.Caption:=inttostr(length(b));//我只要加上这句话,就显示不了了,证明你这种内存拷贝
                                          存在问题。
      copymemory(@c[1],pchar(b),5);//这里也别从第0位copy啦
      memo1.Lines.Add(c);
    end;
      

  12.   

    回复人: venge() ( ) 信誉:100  2005-01-18 17:45:00  得分: 0  
     
     
       不要用move,我就是要用copymemory,我要搞明白静态string它的指针是怎么指的。
      
     
    首先说明一下copymemory和move根本就是一回事,
    copymemory只是对move进行了一下封装,看vcl源代码就可以看到
    然后回到你的问题上
    果然不是我说的那么简单,呵呵
    以前还真的没发现,我这里也是这样试了一下,挺有意思的
    就像这样
    var
      b:string;
      c:string[10];
    begin
      b :='12345678901234567890';
      c:='*****'; //c:='*';  //换成初始化一部分看看,这里最有意思,哈
      //zeromemory(@C[1],sizeof(c)-1); //这句你可以加上看看效果
      caption:=inttostr(length(b));
      copymemory(@c[1],pchar(b),3);
      showmessage(C);
    end;有点意思,哈
      

  13.   

    看来ShortString的空间是编译器根据需要分配的
    定义的长度只不过是它的最大长度罢了
      

  14.   

    而且除非直接操作内存
    否则它是不会越界的,编译器是会自动给它把多余的位数截掉的
    就像这样var
      c:string[5];
    begin
      c:='12345678';
      showmessage(C);//会直显示12345。如果用copymemory,超过5就会报错的
    end;
    还有纠正一下我上面说的,定义的时候不用多定义一位,他的size会自动加1的
    看来比起string,ShortString是相当随意的
      

  15.   

    建议去看看 周爱民得《DELPHI源代码分析》 里面对内部数据类型有详细得分析在说shortstring是为了与老版Pascal兼容才保留到现在的,在程序中尽量不要与String这样的编译器自动维护的类型混用。
      

  16.   

    to chijingde:
        哪到底怎么复制才可以呢?算了,再坚持一天我就结帐。
      

  17.   

    thank u, chijingde.
    我知道怎么回事了