TStringList 常用方法与属性 & DelimitedText空格问题 验证有效

来源:互联网 发布:js 对象 key 变量 编辑:程序博客网 时间:2024/05/17 03:29

测试同事帮反映了我们程序在处理委托时的一个问题:对于港股的委托,我们对它的成交回报中股票代码是空的。

加日志找到原因在这里,港股的委托其股票代码是5位,会左补一个空格,而在delphi中,对于TStringList 进行类似哈希表操作时,DelimitedText会自动判断空格并跳过。

导致reqtext.securityid一直为空,在后续的处理中出错。

function MakePTReqtext(reqtext: PTReqtext; sReqtext:string):Boolean;            //902var  Hash: THashedStringList;  a : TStringList;  fixPkg : TFixPackage;  Buffer : string;begin  Hash := THashedStringList.Create;  Buffer := Trim(sReqtext);  Hash.DelimitedText := Buffer;  Hash.Delimiter := SOH;  reqtext.MsgType := Hash.Values['35'];  reqtext.IOIID := Hash.Values['23'];  reqtext.IOITransType := Hash.Values['28'];  reqtext.IOIRefID := Getbuff2(Hash.Values['26']);  reqtext.clordid := Hash.Values['11'];  reqtext.OrigClOrdID := Getbuff2(Hash.Values['41']);  reqtext.securityid := Hash.Values['48'];                    Simulator.AddLog(1,'解包reqtext.securityid为' +  reqtext.securityid);//对于港股的股票代码是5位,会左补空格,此处就会取空。  reqtext.price := Getbuff(Hash.Values['44']);  reqtext.orderqty := Getbuff(Hash.Values['38']);  reqtext.side := Hash.Values['54'];  reqtext.stockholder := GetGroupValue2(Hash,const_NoPartyIDs, 5);;  reqtext.reportseat := GetGroupValue2(Hash,const_NoPartyIDs, 1);  reqtext.branchcode := GetGroupValue2(Hash,const_NoPartyIDs, 4001);  reqtext.text := Hash.Values['58'];  reqtext.UnderlyingSecurityID := Hash.Values['308'];  reqtext.orderSrc :=  Hash.Values['10901'];  reqtext.PositionEffect :=  Hash.Values['77'];  reqtext.OrdType :=  Hash.Values['40'];  reqtext.TimeInForce :=  Hash.Values['59'];  reqtext.CoveredOrUncovered :=  Hash.Values['203'];  reqtext.OwnerType := Getbuff(Hash.Values['522']);  reqtext.NoDates := Getbuff(Hash.Values['580']);  reqtext.QuoteReqID := Hash.Values['131'];  reqtext.PartyID := Hash.Values['448'];   reqtext.SecondaryOrderID := Trim(Hash.Values['198']);  if reqtext.SecondaryOrderID = '0' then    reqtext.SecondaryOrderID := '';  reqtext.GroupLeges := GetGroupLegesValue2(Hash);  Hash.Free;  Result := True;end;


网上找到对于这个问题的解释及解决方法:


TStringList 常用方法与属性&DelimitedText空格问题//TStringList 常用方法与属性:varList: TStringList;i: Integer;beginList := TStringList.Create;List.Add('Strings1');           {添加}List.Add('Strings2');List.Exchange(0,1);             {置换}List.Insert(0,'Strings3');      {插入}i := List.IndexOf('Strings1'); {第一次出现的位置}List.Sort;                      {排序}List.Sorted := True;   {指定排序}List.Count;                     {总数}List.Text;                      {文本集合}List.Delete(0);                 {删除, 0是第一个数据}List.LoadFromFile('c:/tmp.txt');{打开}List.SaveToFile('c:/tmp.txt'); {保存}List.Clear;                     {清空}List.Free;                      {释放}end;//读入字符串varList: TStringList;beginList := TStringList.Create;List.CommaText := 'aaa,bbb,ccc,ddd';//相当于: List.Text := 'aaa' + #13#10 + 'bbb' + #13#10' + 'ccc' + '#13#10' + 'ddd';ShowMessage(IntToStr(List.Count)); //4ShowMessage(List[0]); //aaaList.Free;end;//置换分隔符varList: TStringList;beginList := TStringList.Create;List.Delimiter := '|';List.DelimitedText := 'aaa|bbb|ccc|ddd';ShowMessage(IntToStr(List.Count)); //4ShowMessage(List[0]); //aaaList.Free;end;//类似的哈希表操作法varList: TStringList;beginList := TStringList.Create;List.Add('aaa=111');List.Add('bbb=222');List.Add('ccc=333');List.Add('ddd=444');ShowMessage(List.Names[1]); //bbbShowMessage(List.ValueFromIndex[1]); //222ShowMessage(List.Values['bbb']); //222//ValueFromIndex 可以赋值:List.ValueFromIndex[1] := '2';ShowMessage(List[1]); //bbb=2//可以通过 Values 赋值:List.Values['bbb'] := '22';ShowMessage(List[1]); //bbb=22List.Free;end;//避免重复值varList: TStringList;beginList := TStringList.Create;List.Add('aaa');List.Sorted := True; //需要先指定排序List.Duplicates := dupIgnore; //如有重复值则放弃List.Add('aaa');ShowMessage(List.Text); //aaa//Duplicates 有3个可选值://dupIgnore: 放弃;//dupAccept: 结束;//dupError: 提示错误.List.Free;end;//排序与倒排序{排序函数}function DescCompareStrings(List: TStringList; Index1, Index2: Integer): Integer;beginResult := -AnsiCompareText(List[Index1], List[Index2]);end;procedure TForm1.Button1Click(Sender: TObject);varList: TStringList;beginList := TStringList.Create;List.Add('bbb');List.Add('ccc');List.Add('aaa');//未排序ShowMessage(List.Text); //bbb ccc aaa//排序List.Sort;ShowMessage(List.Text); //aaa bbb ccc//倒排序List.CustomSort(DescCompareStrings); //调用排序函数ShowMessage(List.Text); //ccc bbb aaa//假如:List.Sorted := True;List.Add('999');List.Add('000');List.Add('zzz');ShowMessage(List.Text); //000 999 aaa bbb ccc zzzend;DelimitedText空格DelimitedText 空格也默认为分割符的原因很简单: Borland的程序员把这个属性对应的write方法中的一行代码多加了一个空格。2种方法解决这个问题。空格问题的解决方法之一:先StringReplace用一个特殊字符替代空格,然后StringReplace回来ss:='aa|bb c| c';ss:= StringReplace(ss,' ','#',[rfReplaceAll]);s:= TStringList.Create;s.Delimiter:= '|';s.DelimitedText:= ss;for i:= 0 to s.Count - 1 dobegins[i]:= StringReplace(s[i],'#',' ',[rfReplaceAll]);memo1.Lines.Add(s[i]);end;空格问题的解决方法之二:找到 {DelphiInstDir}/source/Win32/rtl/common/Classes.pas 文件,知道SetDelimitedText函数。如下所示:注:{DelphiInstDir}为Delphi安装目录procedure TStrings.SetDelimitedText(const Value: string); var P, P1: PChar; S: string; begin BeginUpdate; try Clear; P := PChar(Value); while P^ in [#1..' '] do {$IFDEF MSWINDOWS} P := CharNext(P); {$ELSE} Inc(P); {$ENDIF} while P^ <> #0 do begin if P^ = QuoteChar then S := AnsiExtractQuotedStr(P, QuoteChar) else begin P1 := P; // while (P^ > ' ') and (P^ <> Delimiter) do //源代码while (P^ >= ' ') and (P^ <> Delimiter) do     //修改后的代码  请继续往下看    <span style="color:#6633ff;">为方便携带,可将Classes.pas 文件重新编译到你的工程文件中即可。步骤:工程-添加到工程-Classes.pas</span>


提醒注意:


对于解决方法2,网上有别的文章写修改后的代码应该是改成(p^ > ''),验证了那样是不可以的,应该用>=' ',

因为这里是对ASCII码比较大小,大于空格' '的都是能显示的,应该判断为大于等于空格。

0 0
原创粉丝点击