delphi TStringList DelimitedText空格问题

方法一:

uses IdStrings
var
   sl: TStringList;
   str: string;
   i: Integer;
begin
   str := 'aa,b b,cc,dd';
   sl := TStringList.Create;
   SplitColumns(str, sl, ',');//该函数没有上述的BUG
   for i := 0 to sl.Count - 1 do
      ShowMessage(sl[i]);
   FreeAndNil(sl);
end;

 

方法二:

{

函数功能:使用自定义分隔符分离字符串并以Stringlist返回

参数说明: 

Source: 源字符串

 Deli: 自定义分离符

StringList: 返回分离结果

}

procedure SplitString(Source,Deli:string; var StringList :TStringList);

var
  EndOfCurrentString: Integer;
begin
  if  StringList = nil then exit;
  StringList.Clear;
  while Pos(Deli, Source)>0 do
  begin
    EndOfCurrentString := Pos(Deli, Source);
    StringList.add(Copy(Source, 1, EndOfCurrentString - 1));
    Source := Copy(Source, EndOfCurrentString + length(Deli), length(Source) - EndOfCurrentString);
  end;
  StringList.Add(source);
end;

// 调用
procedure TForm1.Button1Click(Sender: TObject);
var
  strlist: TStringList;
begin
  strlist := TStringList.Create;
  SplitString('123,Channel 1,00000000000000000123,上下线,离线,2013-01-31 09:22:32,公司',
    ',',
    strlist);
  ShowMessage(strlist.Text);
end;

方法三:

在delphi中,对于TStringList 进行类似哈希表操作时,DelimitedText会自动判断空格并跳过。

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

function MakePTReqtext(reqtext: PTReqtext; sReqtext:string):Boolean;            //902
var
  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 常用方法与属性:
var
List: TStringList;
i: Integer;
begin
List := 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;
 
//读入字符串
var
List: TStringList;
begin
List := TStringList.Create;
List.CommaText := 'aaa,bbb,ccc,ddd';
//相当于: List.Text := 'aaa' + #13#10 + 'bbb' + #13#10' + 'ccc' + '#13#10' + 'ddd';
 
ShowMessage(IntToStr(List.Count)); //4
ShowMessage(List[0]); //aaa
 
List.Free;
end;
 
//置换分隔符
var
List: TStringList;
begin
List := TStringList.Create;
List.Delimiter := '|';
List.DelimitedText := 'aaa|bbb|ccc|ddd';
 
ShowMessage(IntToStr(List.Count)); //4
ShowMessage(List[0]); //aaa
 
List.Free;
end;
 
//类似的哈希表操作法
var
List: TStringList;
begin
List := TStringList.Create;
 
List.Add('aaa=111');
List.Add('bbb=222');
List.Add('ccc=333');
List.Add('ddd=444');
 
ShowMessage(List.Names[1]); //bbb
ShowMessage(List.ValueFromIndex[1]); //222
ShowMessage(List.Values['bbb']); //222
 
//ValueFromIndex 可以赋值:
List.ValueFromIndex[1] := '2';
ShowMessage(List[1]); //bbb=2
 
//可以通过 Values 赋值:
List.Values['bbb'] := '22';
ShowMessage(List[1]); //bbb=22
 
List.Free;
end;
 
//避免重复值
var
List: TStringList;
begin
List := 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;
begin
Result := -AnsiCompareText(List[Index1], List[Index2]);
end;
 
procedure TForm1.Button1Click(Sender: TObject);
var
List: TStringList;
begin
List := 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 zzz
end;
 
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 do
begin
s[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     //修改后的代码  请继续往下看
    
 
为方便携带,可将Classes.pas 文件重新编译到你的工程文件中即可。步骤:工程-添加到工程-Classes.pas


提醒注意:

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

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

你可能感兴趣的:(delphi)