views:

278

answers:

5

I have some VB source code and want to convert it to Delphi:

Do While Not EOF(textfile)
Line Input #textfile, Line

Dim retstring() As String         
retstring = Split(Line, Chr(32))
first  = retstring(0)
second = retstring(1)

I have some text file with lines similar to these:

hello all
nice to
good day


I tried some of the source code in the answers, but am still having problems. I see the messages 'hello all' and 'nice to', but actually I want to see 'hello' and 'all' instead.

procedure TForm1.BitBtn1Click(Sender: TObject);
var
  list : TStringList;
  first, second, third: string;
begin
  list := TStringList.Create;
  try
    list.Delimiter := #32;
    list.LoadFromFile('test.txt');
    first := list[0];
    second := list[1];
    ShowMessage(first);
    ShowMessage(second);
  finally
    list.Free;
  end;
end;
+3  A: 

One of the ways to split a string on a delimiter is using a TStringlist:

var
  list : TStringList;

begin
  list := TStringList.Create;
  try
    list.Delimiter := #32;
    list.DelimitedText := 'abc def ghi';
    first := list[0];
    second := list[1];
    third := list[2];
  finally
    list.Free;
  end;
Gamecat
I'm no VB expert but it seems he's trying to load a file. This can be done with a stringlist too. You just have to add list.LoadFromFile('textfile');
johnny
Yes, I know. But the question was about string manipulation. So I assumed he knows how to read a string from a file.
Gamecat
hello thanks! i was modified source based on your method, but still problem procedure TForm1.BitBtn1Click(Sender: TObject);var list : TStringList; first, second, third: string;begin list := TStringList.Create; try list.Delimiter := #32; list.LoadFromFile('c:\test.txt'); first := list[0]; second := list[1]; third := list[2]; ShowMessage(first); ShowMessage(second); ShowMessage(third); finally list.Free; end;end;
paul
A: 

Or if you really want an array you can try this method:

(copied from http://www.delphi3000.com/articles/article_2616.asp?SK=)

  TStringArray = array of string;


  function Split(const str: string;
                 const separator: string): TStringArray;
  // Returns an array with the parts of "str" separated by "separator"
  var
    i, n: integer;
    p, q, s: PChar;
  begin
    SetLength(Result, Occurs(str, separator)+1);
    p := PChar(str);
    s := PChar(separator);
    n := Length(separator);
    i := 0;
    repeat
      q := StrPos(p, s);
      if q = nil then q := StrScan(p, #0);
      SetString(Result[i], p, q - p);
      p := q + n;
      inc(i);
    until q^ = #0;
  end;
birger
hello thanks for your reply..lack of my delphi knowledge ,i can't understand sorry but thanks a lot :)
paul
wow, that does look ugly. I can't imagine anyone to prefer this over the `TStringList` solution.
Smasher
well, this returns an array, and not a stringlist! Ofcourse you could also convert the stringlist to an array, but this will be a little bit slower.
birger
This code seems to fail for perfectly legal strings with embedded #0 characters
Marco van de Voort
+1  A: 

Hi! If you just want to load a textfile for manipulation a Stringlist is handy. Note this is from memory and untested!

procedure loadtext;
var
  vList: TStringList;
  vFirst, vSecond: String; 
  i: Integer;
begin
  vList := TStringList.Create;
  try
    vList.LoadFromFile('myfile.txt');

    for i := 0 to vList.Count-1 do
    begin
      vFirst  := copy(vList[i], 0, pos(vList[i], ''));
      vSecond := copy(vList[i], pos(vList[i], ''), 1000);
    end;
  finally
    FreeAndNil(vList);
  end;  
end;
Roland Bengtsson
+7  A: 

You can use the TStringList Class to split a text file.

see this example :

program SplitTextFile;

{$APPTYPE CONSOLE}

uses
  Classes,
  SysUtils;

var
 Lines : TStringList;
 Split : TStringList;
 i     : Integer;
 j     : Integer;
begin
  Lines := TStringList.Create;
  try
    Lines.LoadFromFile('c:\software\demo.txt'); //assign the file name

    Split := TStringList.Create;
    try
      Split.Delimiter := ' '; // set the delimiter

      for i := 0 to Lines.Count - 1 do //iterate over the lines of the file
      begin
        Split.DelimitedText := Lines[i];
        for j := 0 to Split.Count - 1 do //iterate over the split elements
          Writeln(Split[j]);
      end;
    finally
      Split.Free;
    end;
  finally
    Lines.Free;
  end;

  Readln;
end.
RRUZ
hello..really thanks for your reply..
paul
@RRUZ: It's obvious you know your stuff (+1), but *please* don't use "except" and "finally" at all in such sample code, or do it properly. Writing it like this won't take any more time really.
mghie
+1  A: 

I have a general purpose utility that I have used ever since my Turbo Pascal days which does just what your asking:

function NumStringParts(SourceStr,Delimiter:String):Integer;
var
  offset : integer;
  curnum : integer;
begin
  curnum := 1;
  offset := 1;
  while (offset <> 0) do
    begin
      Offset := Pos(Delimiter,SourceStr);
      if Offset <> 0 then
        begin
          Inc(CurNum);
            Delete(SourceStr,1,(Offset-1)+Length(Delimiter));
        end;
    end;
  result := CurNum;
end;

function GetStringPart(SourceStr,Delimiter:String;Num:Integer):string;
var
  offset : integer;
  CurNum : integer;
  CurPart : String;
begin
  CurNum := 1;
  Offset := 1;
  While (CurNum <= Num) and (Offset <> 0) do
    begin
      Offset := Pos(Delimiter,SourceStr);
      if Offset <> 0 then
        begin
          CurPart := Copy(SourceStr,1,Offset-1);
          Delete(SourceStr,1,(Offset-1)+Length(Delimiter));
          Inc(CurNum)
        end
      else
        CurPart := SourceStr;
    end;
  if CurNum >= Num then
    Result := CurPart
  else
    Result := '';
end;

For your specific case you can do something like the following:

var
  Data : tStringlist;
  iX,iY,iCnt : integer;
begin
  data := tStringlist.create;
  try
    data.loadFromFile( filename );
    for iX := 0 to Data.Count-1 do
    begin
      iCnt := NumStringParts(Data.Strings[ix],#32);
      for iY := 1 to iCnt do
        ShowMessage( GetStringPart(Data.Strings[ix],#32,iY) );
    end;
  finally
    data.free;
  end;
end;

this opens a file filename and then calls CallSomeFunction for every word (delimited by spaces) in your text file.

skamradt
Hi, i was tested your source but something error encounter, im not sure what is problem. i was just changed 'filename' to 'c:\test.txt' and try to execute source but error . thanks
paul
@paul - Corrected. The outer loop should be from 0 to count-1, the inner loop from 1 to count.
skamradt