Solved

Reading part of a line from a text file

Posted on 2003-11-09
14
227 Views
Last Modified: 2010-04-05
I have a code which lets me read lines from a text file and displays each lines content into a separate Edit fields; I want to change it so that i can read parts of the line and not the entire line; for example say I have a text file which contains the following information.

Country France ;
Continent Europe ;
Language French ;


The following is my original code how would I change it so that  read "France" "Europe" "French" in each of my edit fields rather then reading the whole lines.
Note: i want to read the part of the line regardless of the content,  so if the content of the line is changed i still want to be able to read that same part of the line into the corresponding edit field; thanks

var
sl: TStringList;
begin
sl :=TStringList.Create;
sl.LoadFromFile('/home/user/test.txt');
Edit1.Text := sl[0];
Edit2.Text := sl[1];
Edit3.Text := sl[2];
sl.Free;

0
Comment
Question by:itektas
  • 7
  • 6
14 Comments
 
LVL 5

Expert Comment

by:arjanh
ID: 9709590
 temp := Copy( sl[0], Pos(' ', sl[0])+1, Length(sl[0]) );   // everything from the first space
  Edit1.Text := Copy( temp, 1, Pos(' ', temp) );
0
 

Author Comment

by:itektas
ID: 9709613
ok, i get undeclared identifier "temp ; am i missing something somewhere?

var
sl: TStringList;
begin
sl :=TStringList.Create;
temp := Copy( sl[0], Pos(' ', sl[0])+1, Length(sl[0]) );
sl.LoadFromFile('/home/user/test.txt');
Edit1.Text := Copy( temp, 1, Pos(' ', temp) );
sl.Free;
end;
0
 
LVL 5

Accepted Solution

by:
arjanh earned 20 total points
ID: 9709680
Sorry, temp is an extra temporary String variable. It should also be assigned AFTER loading the sl StringList, otherwise sl[0] will give you a violation exception! This should work:

var
  sl: TStringList;
  temp : String;
begin
  sl :=TStringList.Create;
  sl.LoadFromFile('/home/user/test.txt');
 
  temp := Copy( sl[0], Pos(' ', sl[0])+1, Length(sl[0]) );   // everything from the first space
  Edit1.Text := Copy( temp, 1, Pos(' ', temp) );   // Everything up to the first space of temp

  temp := Copy( sl[1], Pos(' ', sl[1])+1, Length(sl[1]) );   // everything from the first space
  Edit2.Text := Copy( temp, 1, Pos(' ', temp) );   // Everything up to the first space of temp

  temp := Copy( sl[2], Pos(' ', sl[2])+1, Length(sl[2]) );   // everything from the first space
  Edit3.Text := Copy( temp, 1, Pos(' ', temp) );   // Everything up to the first space of temp

  sl.Free;
end;
0
Free Tool: Postgres Monitoring System

A PHP and Perl based system to collect and display usage statistics from PostgreSQL databases.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 

Author Comment

by:itektas
ID: 9710022
cool that works now, thanks. :) One thing tho, say when the contents of my text file are

country france ;

then it reads it but if they are

country france;  

 without a space after the semicolon then it doesnt not read it, can i change something so that  i can keep the word and the semicolon together and still read it to the edit field? thanks
0
 
LVL 5

Expert Comment

by:arjanh
ID: 9710278
You could change
  Edit1.Text := Copy( temp, 1, Pos(' ', temp) );
to
  Edit1.Text := Copy( temp, 1, Pos(';', temp) );

Then it reads everything from the first space to the first semicolon. However in case of 'france ;' the edit box would show 'france '. If the extra space is a problem it would get a bit tricky, and that's gonna cost ya more than 20 points :)
0
 

Author Comment

by:itektas
ID: 9710662
Ok  i will set another 30 points? But do i need to open a new question to give you more points or is there another way of doing it? I have done what you said ( adding the extra ';' ) but then when i run the program it displays the semicolon as well, so if the contents of my text file are " france;" then "france;" is displayed in the edit box and if they are "france ;" then that is displayed in the edit box. I would prefer not to have the semicolon displayed, and i think it would also be useful not to have an extra space when I have "France ;" thanks
0
 
LVL 5

Expert Comment

by:arjanh
ID: 9710814
You're in luck. As I had not tested my code, I oversaw that little problem with the ';'. So here is the final, correct, tested version:

function GetSecondWord( Source : String ) : String;
var
  p1,p2,p3 : Integer;
  temp : String;
begin
  p1 := Pos( ' ', Source );
  temp := Copy( Source, p1+1, Length(Source) );
  p2 := Pos( ' ', temp );
  p3 := Pos( ';', temp );

  if p2 = 0 then
    if p3 = 0 then
      Result := temp
    else
      Result := Copy( temp, 1, p3-1 )
  else  // p2 <> 0
    if p3 = 0 then
      Result := Copy( temp, 1, p2-1 )
    else  // p2 <> 0 AND p3 <> 0
      if p2 > p3 then
        Result := Copy( temp, 1, p3-1 )
      else
        Result := Copy( temp, 1, p2-1 )
end;

procedure TForm1.Button1Click(Sender: TObject);    // OR whatever your procedure is called!
var
  sl: TStringList;
begin
  sl :=TStringList.Create;
  sl.LoadFromFile('/home/user/test.txt');

  Edit1.Text := GetSecondWord( sl[0] );
  Edit2.Text := GetSecondWord( sl[1] );
  Edit3.Text := GetSecondWord( sl[2] );

  sl.Free;
end;



If you want to, you could create a new question in this topic area with the title "Points for arjanh re: Question 20792222". In the body of the new question, post the URL of the original question, and in this question post the URL of that new question.
But don't feel obliged...
0
 

Author Comment

by:itektas
ID: 9710835
wow, the code suddenly got quiet complicated, i dont really understand what happens behind that :/ is there like an easier way that i could just remove the inital problem where the ";" appeared after france? as the extra space seems to make the coding quiet confusing! I will do what you said now for the points, also is there any websites that you would recommend me to learn about the text files manupilating? I have a book on Delphi 7 and Kylix but i find it difficult to find relevant information for what i want to do with text files. thanks
0
 

Author Comment

by:itektas
ID: 9710850
0
 

Author Comment

by:itektas
ID: 9710852
my bad , wrote the wrong url, this one should be correct

http://www.experts-exchange.com/Programming/Programming_Languages/Delphi/Q_20792417.html
0
 
LVL 5

Expert Comment

by:arjanh
ID: 9710904
We agree on the code being more complex than it ought to be. So here is an improved version (my motto: get it working; get it right; get it optimized).

function GetSecondWord( Source : String ) : String;
var
  p1,p2 : Integer;
  temp : String;
begin
  p1 := Pos( ' ', Source );
  temp := Copy( Source, p1+1, Length(Source) );

  // replace the first space (if any) with ';'
  temp := StringReplace( temp, ' ', ';', [] );

  // Now return everything up to the first ';'
  p2 := Pos( ';', temp );
  if p2 = 0 then
    Result := temp
  else
    Result := Copy( temp, 1, p2-1 );
end;


I don't know any relevant books. Just play around a lot with it, I guess :)
And the Delphi help pages (F1 within the IDE) are also helpful. And search the web, or ask here.
But hands-on experience seems the best way....
0
 

Author Comment

by:itektas
ID: 9711179
that works perfectly, but can you briefly explain me what this bit of coding actually does

  p1 := Pos( ' ', Source );
  temp := Copy( Source, p1+1, Length(Source) );
 
temp := StringReplace( temp,' ', ';', [] );

  p2 := Pos( ';', temp );
  if p2 = 0 then
    Result := temp
  else
    Result := Copy( temp, 1, p2-1 );

by pasting it and changing the "p2" to "p3" then "p4"... I can add more edit fields to my program, all i want to be able to do is to be able to read say for example a third word rather then the second but i cant change the coding as i dont really understand what it does. thanks a lot
0
 
LVL 5

Expert Comment

by:arjanh
ID: 9712678
[example string = 'a b ;']

>   p1 := Pos( ' ', Source );
p1 is the index of the first space within the string Source. If no space is found, Pos returns 0. If you place your cursor on the word Pos and press F1, you get the online help for the Pos function. Very handy!
[p1 = 2]

>   temp := Copy( Source, p1+1, Length(Source) );
temp is the substring of Source that starts 1 position AFTER the space (so the first character of the word). The third parameter is the length of the substring you want to copy, if this value is larger than the remainder of the source string, just the remainder is returned.
[temp = Copy('a b ;', 3, 5) = 'b ;']

> temp := StringReplace( temp,' ', ';', [] );
Replace the first space found in temp with a semicolon.
[temp = 'b;;']

>   p2 := Pos( ';', temp );
p2 is the index of the first ';'
[p2 = 2]

>   if p2 = 0 then
This happens if temp doesn't contain any ';' at all

>     Result := temp
So we return the whole substring

>   else
Otherwise (P2 <> 0)

>     Result := Copy( temp, 1, p2-1 );
Get the substring from temp that starts at position 1 and has a length of p2-1, which is the character just before the ';'
[Result = Copy('b;;',1,1) = 'b']
0
 

Expert Comment

by:ManChesTer
ID: 9717064
function index(t:String):String;
var
 p  : Integer;
 i  : String;
begin
 p:=pos(' ',t);
 i:=copy(t,p+1,length(t));
 result:=copy(t,1,p-1)+'='+copy(i,1,pos(' ',i)-1);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
 sl : TStringList;
 j  : Integer;
begin
 sl :=TStringList.Create;
//sl.LoadFromFile('/home/user/test.txt');
 sl.Add('Country France ;');
 sl.Add('Continent Europe ;');
 sl.Add('Language French ;');
 for j:=0 to sl.Count-1 do
  sl[j]:=index(sl[j]);
 edit1.Text:=sl.Values['Country'];
 edit2.Text:=sl.Values['Continent'];
 edit3.Text:=sl.Values['Language'];
 sl.Free;
end;

Good coding....

ManChesTer.
0

Featured Post

Networking for the Cloud Era

Join Microsoft and Riverbed for a discussion and demonstration of enhancements to SteelConnect:
-One-click orchestration and cloud connectivity in Azure environments
-Tight integration of SD-WAN and WAN optimization capabilities
-Scalability and resiliency equal to a data center

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
Hello everybody This Article will show you how to validate number with TEdit control, What's the TEdit control? TEdit is a standard Windows edit control on a form, it allows to user to write, read and copy/paste single line of text. Usua…
Two types of users will appreciate AOMEI Backupper Pro: 1 - Those with PCIe drives (and haven't found cloning software that works on them). 2 - Those who want a fast clone of their boot drive (no re-boots needed) and it can clone your drive wh…

830 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question