[英]How can I loop through a delimited string and assign the contents of the string to local delphi variables?
我已经编写了一个Delphi函数,该函数将.dat文件中的数据加载到字符串列表中。 然后,它解码字符串列表并分配给字符串变量。 字符串的内容使用“#”符号作为分隔符。
然后,如何获取该字符串的内容,然后将其内容分配给局部变量?
// Function loads data from a dat file and assigns to a String List.
function TfrmMain.LoadFromFile;
var
index, Count : integer;
profileFile, DecodedString : string;
begin
// Open a file and assign to a local variable.
OpenDialog1.Execute;
profileFile := OpenDialog1.FileName;
if profileFile = '' then
exit;
profileList := TStringList.Create;
profileList.LoadFromFile(profileFile);
for index := 0 to profileList.Count - 1 do
begin
Line := '';
Line := profileList[Index];
end;
end;
解码后,变量“ Line”包含如下内容:
例:
Line '23#80#10#2#1#...255#'.
并非所有分隔符之间的值都具有相同的长度,并且每次调用LoadFromFile函数时,“ Line”的值都会变化(例如,有时一个值在接下来的两个或三个中可能只有一个数字,所以我不能依靠字符串或数组的复制功能)。
我试图找出一种循环遍历“行”内容,将其分配给名为“缓冲区”的局部变量的方法,然后如果遇到“#”,则会将缓冲区的值分配给局部变量,将缓冲区重新初始化为“”; 然后移到“行”中的下一个值,每次对下一个参数重复该过程,而忽略“#”。
我认为我已经很久没有解决这个问题了,我似乎无法取得任何进展,需要有所突破。 如果有人愿意看一看,我欢迎任何有关如何实现的建议。
非常感谢
KD
您需要第二个TStringList:
lineLst := TStringList.Create;
try
lineLst.Delimiter := '#';
lineLst.DelimitedText := Line;
...
finally
lineLst.Free;
end;
如果行包含空格,则可以根据您的Delphi版本设置lineLst.StrictDelimiter := true
。
您可以执行以下操作:
program Project1;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils, StrUtils;
var
S : string;
D : string;
begin
S := '23#80#10#2#1#...255#';
for D in SplitString(S,'#') do //SplitString is in the StrUtils unit
writeln(D);
readln;
end.
您没有标记您的Delphi版本,所以我不知道它是否适用。 这是特定于版本的。 请做!
为了我个人的喜好:
1:下载Jedi CodeLib- http ://jcl.sf.net。 然后使用TJclStringList。 它有很好的拆分方法。 之后,您只需要遍历即可。
函数Split(const AText,ASeparator:string; AClearBeforeAdd:Boolean = True):IJclStringList;
uses JclStringLists;
...
var s: string; js: IJclStringList.
begin
...
js := TJclStringList.Create().Split(input, '#', True);
for s in js do begin
.....
end;
...
end;
2:Delphi现在具有功能较弱的StringSplit例程。 http://docwiki.embarcadero.com/Libraries/zh-CN/System.StrUtils.SplitString它具有一个缺点,即字符串类型的数组可能与其自身不兼容。 您好,1949年的Pascal规则...
uses StrUtils;
...
var s: string;
a_s: TStringDynArray;
(* aka array-of-string aka TArray<string>. But you have to remember this term exactly*)
begin
...
a_s := SplitString(input, '#');
for s in a_s do begin
.....
end;
...
end;
3:使用TStringList。 它的主要问题是,其设计是空格或换行符是内置的分隔符。 在较新的Delphi中可以将其抑制。 总体而言,代码应适合您的确切Delphi版本。 您可以轻松地在Google上查找诸如“使用TStringlist拆分字符串”之类的内容,并获取大量示例(例如@Uwe的示例)。
但是您可能会忘记在这里或那里进行抑制。 您可能在旧的Delphi上,而那是无法做到的。 您可能会误将示例用于其他Delphi版本。 而且...这很无聊:-)尽管您可以创建自己的函数来为您生成这种预先调整的字符串列表,并仔细检查其中的Delphi版本:-)但是,在使用后,您必须仔细释放该对象。
我使用我编写的名为Fetch
的函数。 我想我前一段时间从Indy图书馆偷走了这个主意:
function Fetch(var VString: string; ASeperator: string = ','): string;
var LPos: integer;
begin
LPos := AnsiPos(ASeperator, VString);
if LPos > 0 then
begin
result := Trim(Copy(VString, 1, LPos - 1));
VString := Copy(VString, LPos + 1, MAXINT);
end
else
begin
result := VString;
VString := '';
end;
end;
然后我会这样称呼它:
var
value: string;
line: string;
profileFile: string;
profileList: TStringList;
index: integer;
begin
if OpenDialog1.Execute then
begin
profileFile := OpenDialog1.FileName;
if (profileFile = '') or not FileExists(profileFile) then
exit;
profileList := TStringList.Create;
try
profileList.LoadFromFile(profileFile);
for index := 0 to profileList.Count - 1 do
begin
line := profileList[index];
Fetch(line, ''''); //discard "Line '"
value := Fetch(line, '#')
while (value <> '') and (value[1] <> '''') do //bail when we get to the quote at the end
begin
ProcessTheNumber(value); //do whatever you need to do with the number
value := Fetch(line, '#');
end;
end;
finally
profileList.Free;
end;
end;
end;
注意:这是在浏览器中输入的,因此我没有检查它是否有效。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.