Go Premium for a chance to win a PS4. Enter to Win

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 244
  • Last Modified:

Reading part of a line from a text file

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
itektas
Asked:
itektas
  • 7
  • 6
1 Solution
 
arjanhCommented:
 temp := Copy( sl[0], Pos(' ', sl[0])+1, Length(sl[0]) );   // everything from the first space
  Edit1.Text := Copy( temp, 1, Pos(' ', temp) );
0
 
itektasAuthor Commented:
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
 
arjanhCommented:
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
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
itektasAuthor Commented:
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
 
arjanhCommented:
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
 
itektasAuthor Commented:
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
 
arjanhCommented:
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
 
itektasAuthor Commented:
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
 
itektasAuthor Commented:
my bad , wrote the wrong url, this one should be correct

http://www.experts-exchange.com/Programming/Programming_Languages/Delphi/Q_20792417.html
0
 
arjanhCommented:
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
 
itektasAuthor Commented:
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
 
arjanhCommented:
[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
 
ManChesTerCommented:
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

Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

  • 7
  • 6
Tackle projects and never again get stuck behind a technical roadblock.
Join Now