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

在处理港股委托时遇到问题,由于股票代码左补空格,TStringList的DelimitedText属性在进行哈希表操作时会忽略空格,导致数据处理错误。解决方案是正确判断ASCII码,确保大于等于空格的字符被识别。

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

加日志找到原因在这里,港股的委托其股票代码是5位,会左补一个空格,而在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);;
<think> 我们有一个TStringList,其中存储了键值对,例如: A=111 B=222 C=333 D=444 现在需要将其转换为字符串:'A=111&B=222&C=333&D=444' 注意:TStringList的每一行是一个字符串,格式为“键=值”。 我们可以遍历TStringList,将每一行用'&'连接起来。 但是注意:如果TStringList中原本就有'&'字符,可能会影响结果,但根据题意,我们假设键值对中不包含'&'(因为题目要求输出格式就是用'&'连接)。 步骤: 1. 创建一个TStringList对象(假设已经存在并填充了数据)。 2. 使用一个循环或者使用Delphi的字符串连接函数来构建结果字符串。 我们可以使用TStringListDelimitedText属性,但它默认使用引号和空格,而且分隔符只能是单个字符(默认是逗号)。但是我们可以设置: - 将Delimiter设置为'&' - 将QuoteChar设置为#0(避免引号出现) 但是注意:如果键或值中包含了空格,那么使用DelimitedText会在空格处断开,所以这种方法不保险。 另一种方法:手动遍历并连接。 例如: var i: Integer; ResultStr: string; begin ResultStr := ''; for i := 0 to StringList.Count - 1 do begin if ResultStr <> '' then ResultStr := ResultStr + '&'; // 除了第一个,每个前面加一个& ResultStr := ResultStr + StringList[i]; end; 但是这样在第一个元素前面不会加'&',所以是可行的。 考虑到效率,我们可以使用TStringBuilder(但是Delphi7没有TStringBuilder,所以我们可以用简单的字符串连接,因为数据量不大)。 因此,我们给出如下代码: 假设有一个TStringList对象叫做MyList,已经包含了键值对。 代码如下: function BuildKeyValueString(AList: TStringList): string; var i: Integer; begin Result := ''; if AList.Count > 0 then begin Result := AList[0]; for i := 1 to AList.Count - 1 do Result := Result + '&' + AList[i]; end; end; 另一种写法:使用While循环,但使用For循环更清晰。 或者,我们也可以使用TStringList的Text属性,然后替换换行符。但是换行符在不同系统可能不同(Windows是CRLF,Linux是LF),而且我们的字符串中可能包含换行符(但题目中键值对是简单的,没有换行符)。所以可以这样: Result := StringReplace(AList.Text, #13#10, '&', [rfReplaceAll]); 但是这样最后会多出一个'&',因为Text属性最后也有一个换行符(即最后一行后面也有换行)。所以我们需要去掉最后一个多余的'&'。 另一种方法:设置TStringList的Delimiter和StrictDelimiter(Delphi7可能没有StrictDelimiter,Delphi6没有,Delphi7也没有,这个属性是后来添加的),所以这种方法Delphi7中不可靠。 因此,我们采用第一种手动连接的方法。 下面给出完整示例代码: 假设在按钮事件中,我们将一个TStringList的内容转换成字符串并显示。 </think> 在 Delphi 7 中,将 `TStringList` 对象中的键值对转换为 `'A=111&B=222&C=333&D=444'` 格式的实现代码如下: ```delphi function FormatKeyValuePairs(StringList: TStringList): string; var i: Integer; begin Result := ''; for i := 0 to StringList.Count - 1 do begin // 跳过空行和非键值对格式的行 if (StringList[i] <> '') and (Pos('=', StringList[i]) > 0) then begin if Result <> '' then Result := Result + '&'; // 添加分隔符 Result := Result + StringList[i]; end; end; end; ``` ### 使用示例: ```delphi procedure TForm1.Button1Click(Sender: TObject); var MyList: TStringList; FormattedString: string; begin MyList := TStringList.Create; try // 添加键值对数据 MyList.Add('A=111'); MyList.Add('B=222'); MyList.Add('C=333'); MyList.Add('D=444'); // 格式转换 FormattedString := FormatKeyValuePairs(MyList); // 显示结果 (示例) ShowMessage(FormattedString); // 输出: A=111&B=222&C=333&D=444 finally MyList.Free; end; end; ``` ### 关键点说明: 1. **循环处理**:遍历 `TStringList` 的每个元素(索引从 0 到 `Count-1`) 2. **格式验证**:过 `Pos('=',...)` 确保只处理有效的键值对格式 3. **连接符处理**: - 首个元素不加 `&` - 后续元素前添加 `&` 分隔符 4. **内存管理**:使用 `try/finally` 确保 `TStringList` 对象正确释放 ### 进阶用法: 若要处理带特殊字符的值(如 `&`),可使用 URL 编码: ```delphi uses HTTPApp; // 在循环内替换: Result := Result + HTTPEncode(StringList[i]); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值