我编写了一个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;
在解码后,var“Line”包含如下内容:
示例:
Line '23#80#10#2#1#...255#'.
并非所有分隔符之间的值都是相同的长度,并且每次调用函数LoadFromFile时“Line”的值都会变化(例如,有时一个值可能只有一个数字,接下来的两个或三个等等所以我不能依赖于字符串或数组的复制功能。)
我试图想出一种循环“Line”内容的方法,将它分配给一个名为“buffer”的局部变量,然后如果遇到'#',则将缓冲区的值赋给a局部变量,将缓冲区重新初始化为'';然后移动到“Line”中的下一个值,重复下一个参数的过程,每次都忽略'#'。
我想我现在已经解决了这个问题太长时间了,我似乎无法取得任何进展,需要休息一下。如果有人愿意看一看,我会欢迎任何关于如何实现这一目标的建议。
非常感谢
KD
答案 0 :(得分:7)
您需要第二个TStringList:
lineLst := TStringList.Create;
try
lineLst.Delimiter := '#';
lineLst.DelimitedText := Line;
...
finally
lineLst.Free;
end;
根据您的Delphi版本,您可以设置lineLst.StrictDelimiter := true
,以防该行包含空格。
答案 1 :(得分:1)
您可以这样做:
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.
答案 2 :(得分:0)
您没有标记您的Delphi版本,所以我不知道它是否适用。 这是特定于版本的。请做!
根据个人喜好:
1:下载Jedi CodeLib - http://jcl.sf.net。然后使用TJclStringList。它有非常好的分割方法。之后你只需要迭代。
function 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/en/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进行类似&#34;使用TStringlist分割字符串&#34;并获得大量示例(例如@Uwe&#39;)。
但是你可能会忘记在这里或那里压抑。你可能在旧的德尔福,在那里无法做到。你可能会错误地应用不同的Delphi版本的例子。并且...它很无聊:-)虽然您可以自己创建函数来为您生成这样的预先调整的字符串列表并仔细检查其中的Delphi版本:-)然后您必须在使用后小心地释放该对象。
答案 3 :(得分:0)
我使用了一个名为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;
注意:这是在浏览器中输入的,所以我没有检查它是否有效。