0

.datファイルから文字列リストにデータをロードするDelphi関数を作成しました。次に、文字列リストをデコードし、文字列変数に割り当てます。文字列の内容は、区切り記号として「#」記号を使用します。

次に、この文字列の内容を取得して、その内容をローカル変数に割り当てるにはどうすればよいですか?

// 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#'.

セパレータ間のすべての値が同じ長さであるとは限らず、「Line」の値は、関数LoadFromFileが呼び出されるたびに変化します(たとえば、値の数が1つだけで、次の2つまたは3つなど、信頼できない場合があります)。文字列または配列のコピー機能)。

「Line」の内容をループして「buffer」というローカル変数に割り当て、「#」が見つかった場合は、bufferの値をローカル変数に割り当てる方法を見つけようとしています。バッファを''に再初期化します。次に、「行」の次の値に移動し、毎回「#」を無視して次のパラメータのプロセスを繰り返します。

私はこの問題に長い間悩まされてきたと思います。私は何の進展も見られず、それから抜け出す必要があるようです。誰かが見てみたいと思うなら、これがどのように達成されるかについての提案を歓迎します。

どうもありがとう

K D

4

4 に答える 4

7

2 つ目の TStringList が必要です。

  lineLst := TStringList.Create;
  try
    lineLst.Delimiter := '#';
    lineLst.DelimitedText := Line;
    ...
  finally
    lineLst.Free;
  end;

lineLst.StrictDelimiter := trueDelphi のバージョンによっては、行にスペースが含まれている場合に備えて設定できます。

于 2012-08-14T14:50:48.110 に答える
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.
于 2012-08-14T16:45:36.983 に答える
0

と呼ばれる私が書いた関数を使用しますFetch。少し前にインディライブラリからアイデアを盗んだと思います:

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;

注: これはブラウザに入力したものなので、動作は確認していません。

于 2012-08-16T09:37:51.650 に答える
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年のパスカル規則...

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 バージョンに合わせて調整する必要があります。「TStringlist を使用して文字列を分割する」のようなものを簡単に Google で検索して、大量の例 (@Uwe のものなど) を取得できます。

しかし、どこかで抑制を忘れるかもしれません。そして、それができない古い Delphi を使用している可能性があります。また、Delphi のバージョンが異なると、例を誤って適用する可能性があります。そして...それはただ退屈です:-)そのような事前調整された文字列リストを生成する独自の関数を作成し、その中のDelphiバージョンを注意深くチェックすることはできます:-)しかし、使用後にそのオブジェクトを慎重に解放する必要があります.

于 2012-08-14T14:52:08.893 に答える