2010. december 7., kedd

How to parse TAB delimited text files


Problem/Question/Abstract:

How would I go about parsing TAB delimited text files? I'm having difficulty with the chr(9) character.

Answer:

Solve 1:

{ ... }
var
  t: Textfile;
  line: string;
  elements: TStringlist;
begin
  Assignfile(t, filename);
  Reset(t);
  try
    elements := TStringlist.Create;
    try
      while not Eof(t) do
      begin
        ReadLn(t, line);
        {The following ignores empty lines}
        if IScan(#9, line, 1) > 0 then
        begin
          elements.clear;
          SplitString(line, #9, elements);
          ProcessElements(elements); {you write this}
        end;
      end;
    finally
      elements.Free
    end;
  finally
    Closefile(t);
  end;

{Return the position of the first instance of ch in S after position fromPos, or 0 if ch was not found}

function IScan(ch: Char; const S: string; fromPos: Integer): Integer;
var
  i: Integer;
begin
  Result := 0;
  for i := fromPos to Length(S) do
  begin
    if S[i] = ch then
    begin
      Result := i;
      Break;
    end;
  end;
end;

{Split the passed string into substrings at the position of the separator character and add the substrings to the passed list. The list is not cleared first!}

procedure SplitString(const S: string; separator: Char; substrings: TStrings);
var
  i, n: Integer;
begin
  if Assigned(substrings) and (Length(S) > 0) then
  begin
    i := 1;
    repeat
      n := IScan(separator, S, i);
      if n = 0 then
        n := Length(S) + 1;
      substrings.Add(Copy(S, i, n - i));
      i := n + 1;
    until
      i > Length(S);
  end;
end;


Solve 2:

procedure DelimitedListToStringList(const S: AnsiString; Delimiter: Char;
  List: TStrings; NullValue: AnsiString);
var
  iPos: Integer;
  Temp, Temp1: AnsiString;
begin
  if not Assigned(List) then
    Exit;
  List.Clear;
  Temp := S;
  iPos := Pos(Delimiter, S);
  while iPos > 0 do
  begin
    SetLength(Temp1, iPos - 1);
    Temp1 := Copy(Temp, 1, iPos - 1);
    if Temp1 = '' then
    begin
      SetLength(Temp1, Length(NullValue));
      Temp1 := NullValue;
    end;
    List.Add(Temp1);
    Delete(Temp, 1, iPos);
    iPos := Pos(Delimiter, Temp);
  end;
  if Temp > '' then
    List.Add(Temp);
end;

Nincsenek megjegyzések:

Megjegyzés küldése