在delphi2010下,stringlist中的字符是以widestring的类型存储的,现在我将一个#$A8字符存储进去,但读取的时候却成了#0,不知道这是怎么回事,该怎么解决此问题呢?请遇见过的网友给个建议,谢谢了!

解决方案 »

  1.   

    简化一下,情形就是这样的,你看看最后的tmpStr就是#0了
    var
      tmpStrList:TStringList;
      tmpStr:AnsiString;
    begin
      tmpStrList:=TStringList.create;  
      tmpStrList.add('a=test');   
      tmpStr:=ansiChar(168);//#$A8    
      tmpStrList.Values['a']:=tmpStr;
      tmpStr:=tmpStrList.Values['a'];//tmpStr就变成#0了
    end;
      

  2.   


    var
      tmpStrList:TStringList;
      tmpStr:AnsiString;
    begin
      tmpStrList:=TStringList.create;   
      tmpStrList.add('a=test');   
      tmpStr:=ansiChar(168);//#$A8   
      tmpStrList.Values['a']:=tmpStr;
      tmpStr:=tmpStrList.Values['a'];//tmpStr就变成#0了
    end;
      

  3.   

    那就用AnsiString吧,所以做delphi程序,变量类型尽量符合delphi自身规则,不然以后个版本间的升级可就麻烦了,2010中包括char,pchar都和之前的版本不一样了
      

  4.   

    我是用的AnsiString,但是Stringlist内部用的string,所以我的#$A8进入Stringlist后就被改成#0了,这才是我郁闷的地方,难不成要我改造Stringlist及TStrings基类才行?郁闷啊!
      

  5.   

    是你搞錯了 ,你知道ansiChar(168)會得到什么?ASCII——單字節字符集(SBCS),最多只到127,你在D2009試看看會得到什么?
      

  6.   

    你先转成WideString,然后加进去,读出来的时候再转成AnsiString
      

  7.   

    我这句是没问题的,ansiChar中的参数最大为255,在delphi2010中是这样的
    关键的问题是从ansiString到String的赋值会出现字符丢失
      

  8.   

    怎么把AnsiString转换为wideString呢?不知道用哪个函数?
      

  9.   

    你怎么確定沒問題?
    1、請回答Ansichar得到的字符編碼是什么?
    2、假設能夠得到,預期結果又是什么?
      

  10.   

    我试过了,确定问题不在这里,在AnsiString与String的转换问题上
    具体演示见截图http://sunjunbo.com/documents/TempImages/AnsiString与String问题截图1.jpg
    http://sunjunbo.com/documents/TempImages/AnsiString与String问题截图2.jpg
      

  11.   

    唉....
    那你知道$A8 又是什么呢?
    AnsiChar(168)得到的是不是應為可理解的字符呢?很顯然,這個轉換并不能得到預期的結果,請參考ASCII對照表,轉化結果應該與這個表相符合,不然這樣的轉換又有何意義?問題應該回到你的原點:你想實現什么?為什么需要Ansichar執行這樣的轉換?
      

  12.   

    这是用来和设备通讯的,$A8是一个设备的标识符,我要保存起来,并发送给下位机,但我用的clientsocket发送的字符串为ansiString,所以我在处理过程中也得将数据转换为AnsiString,否则对方收到的数据不正确
    问题是:AnsiChar转换出来的结果能保存在AnsiString,但不能保存到string中
      

  13.   

    TStringList的问题在我以前的贴中遇到过
    http://topic.csdn.net/u/20100121/20/6a051e08-c744-4042-b53a-b76f1af669d7.html
    我研究了半天,实际上也没解决TStringList的Unicode问题
    关于TStringList中的unicode感觉除非自己重新以非unicode方式重构这个类.否则无法解决转码的问题
    不行的话,只能用List或动态数组了
      

  14.   

    这个问题和unicode没关系,你用同样(ansichar(168))的方式,在D2009以下版本,也一样取不到“东西”,具体原因要跟踪一下cpu view
      

  15.   

    我认为 avan_lau 的回答是对的,
    1.是否一定需要这样的转换操作?
    2.能否用别的方法?
      

  16.   

    时至今日,已经不能再用过去的方法了。在以前,AnsiString不仅可以表示字符串,还可以表示“字节流”,所以才会有诸多用法。当你将一个AnsiString赋值给WideString/UnicodeString时,系统会根据当前的系统代码页进行转换(严格来说,是根据该字符串的代码页进行转换)。作为ANSI编码(MBCS),单独一个$A8是没有意义的(它仅表示一个前导字节,后面还需要一个尾随字节),所以才会丢失。我给你的建议是放弃TStringList作为字节流的想法。另外,在D2009/2010中,string实际上是UnicodeString,它和WideString采用的编码方式是一致的,均为UTF16-LE,但是WideString是和COM兼容的,而且没有引用计数。
      

  17.   

    tmpStr:=ansiChar(168);//#$A8   tmpStr:=Char(168);//#$A8   
    tmpStr:=UnicodeString(ansiChar(168));// 不记得是 这个还是直接用String了。
      

  18.   

    谢谢诸位网友的热心建议,假期过得好吧!我觉得这位网友的说法有道理,应该是没有尾随字节,才会丢失的。
    我已经放弃TStringList存储字节流了,自己写了一个TAnsiStringList类用来存储,重写也不太麻烦,只是按照自己的需求构造了一下,也不知道效率如何,一会儿吃过饭贴出来看看,请诸位网友提意见。
      

  19.   

    我自己写的TAnsiStringList   type TAnsiStringList=class(TPersistent)
      private
        FText:AnsiString;
        FCount:Integer;
        NameSeparator:AnsiString;
        RowSeparator:AnsiString;
        function GetValues(const Names: AnsiString): AnsiString;
        procedure SetValues(const Names, Value: AnsiString);
        function GetCount: Integer;
        function GetText: AnsiString;
      published
      public
        constructor Create;
        property Text:AnsiString Read GetText write FText;
        property Values[const Names:AnsiString]:AnsiString read GetValues write SetValues;
        property Count:Integer Read GetCount;
        function Add(S:AnsiString):integer;
        procedure Assign(Source:TPersistent);
      end;{ TAnsiStringList }procedure TAnsiStringList.Assign(Source: TPersistent);
    begin
      if Source is TAnsiStringList then
      begin
        Self.FText:=TAnsiStringList(Source).FText;
        Self.FCount:=TAnsiStringList(Source).FCount;
        Self.NameSeparator:=TAnsiStringList(Source).NameSeparator;
        Self.RowSeparator:=TAnsiStringList(Source).RowSeparator;
      end;
    end;constructor TAnsiStringList.Create;
    begin
      RowSeparator:=#$D#$A;
      NameSeparator:='=';
      FText:=RowSeparator;
      FCount:=0;
    end;function TAnsiStringList.Add(S: AnsiString): integer;
    begin
      FText:=FText+S+RowSeparator;
      FCount:=FCount+1;
    end;function TAnsiStringList.GetCount: Integer;
    begin
      Result:=FCount;
    end;function TAnsiStringList.GetText: AnsiString;
    begin
      Result := FText;
      delete(Result,1,Length(RowSeparator));
    end;function TAnsiStringList.GetValues(const Names: AnsiString): AnsiString;
    var
      P:integer;
      tmpStr,NameStr:AnsiString;
    begin
      Result:='';
      tmpStr:=FText;
      NameStr:=RowSeparator+Names+NameSeparator;
      p:=pos(NameStr,tmpStr);
      if p<>0 then
      begin
        delete(tmpStr,1,p+length(NameStr)-1);
        Result:=Copy(tmpStr,1,Pos(RowSeparator,tmpStr)-1);
      end;
    end;procedure TAnsiStringList.SetValues(const Names, Value: AnsiString);
    var
      CurrValue,tmpStr,BeforeStr,NameStr:AnsiString;
      P:integer;
    begin
      tmpStr:=FText;
      NameStr:=RowSeparator+Names+NameSeparator;
      P:=pos(NameStr,tmpStr);
      if P<>0 then
      begin
        BeforeStr:=Copy(tmpStr,1,P-1);
        delete(tmpStr,1,P+length(NameStr)-1);
        delete(tmpStr,1,pos(RowSeparator,tmpStr)-1);
        FText:=BeforeStr+RowSeparator+Names+NameSeparator+Value+tmpStr;
      end;
    end;
      

  20.   

    为什么不直接用泛型呢???? TList<AnsiString>