繁体   English   中英

如何遍历定界字符串并将字符串内容分配给本地delphi变量?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM