簡體   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