1

I made a simple program that adds ones information (Name, surname, ID ect) to a .txt file. When ever I make new details in the program, and click on a button to save the information, it rewrites it in the .txt file.

Here's my code:

procedure TForm1.BitBtn1Click(Sender: TObject);
var
  InfoFile                 : TStringList;
  Name, Surname, ExtraInfo : String;
  PhoneNumber,ID           : Integer;
  Date                     : TDateTime;
begin
  InfoFile := TStringList.Create;
  Name := edtName.text;
  Surname := edtSurname.Text;
  ID := StrToInt64(edtID.Text);
  PhoneNumber := StrToInt64(edtPhone.Text);
  Date := StrToDate(edtJoinDate.Text);

  try
    InfoFile.Add('NAME: '+Name);
    InfoFile.Add('SURNAME: '+Surname);
    InfoFile.Add('ID NUMBER: '+IntToStr(ID));
    InfoFile.Add('PHONE NUMBER: '+IntToStr(PhoneNumber));
    InfoFile.Add('DATE JOINED :'+DateToStr(Date));
    InfoFile.Add('');         // Spacers to separate next set of details
    InfoFile.Add('');

    InfoFile.SaveToFile('C:\Users\GrassMan\Desktop\InfoSaver\imfofile.txt');
  finally
    InfoFile.Free;
  end;

So instead of ADDING new details to the .txt file, its rewriting it. I know im doing something, if someone wouldn't mind giving me a hand.

Thanks

2
  • 3
    You need to load the original file first (InfoFile.LoadFromFile('<the file you saved before>');). Commented Mar 2, 2014 at 16:13
  • TLama is quite right. The next thing to do is to work out a way for your program to select and operate on one of the records you save. Maybe read up on TStringGrid or similar. Commented Mar 2, 2014 at 16:20

4 Answers 4

4

Either load the file at the beginning (via LoadFromFile), before adding to it and writing it back; or else forget about TStringList, and just use WriteLn, after opening the file with Append.

Sign up to request clarification or add additional context in comments.

Comments

1

Should look like this:

begin
    InfoFile := TStringList.Create;
    Name := edtName.text;
    Surname := edtSurname.Text;
    ID := (edtID.Text);
    PhoneNumber :=(edtPhone.Text);
  try
    InfoFile.LoadFromFile('C:\Users\grassman\Desktop\infofile.txt');
    InfoFile.Add('NAME: '+Name);
    InfoFile.Add('SURNAME: '+Surname);
    InfoFile.Add('ID NUMBER: '+ ID);
    InfoFile.Add('PHONE NUMBER: '+(PhoneNumber));
    InfoFile.Add('Time of registration: ' + TimeToStr(time));
    InfoFile.Add('Date of registration: ' + DateToStr(date));
    InfoFile.Add('');         // Spacers to separate next set of details
    InfoFile.Add('');
    InfoFile.SaveToFile('C:\Users\grassman\Desktop\infofile.txt');
  finally
    InfoFile.Free;

Comments

1
procedure TForm1.BitBtn1Click(Sender: TObject);
var
  InfoFile                 : TStringList;
  Name, Surname, ExtraInfo : String;
  PhoneNumber,ID           : Integer;
  Date                     : TDateTime;
  FS                       : TFileStream;
begin
 Name := edtName.text;
  Surname := edtSurname.Text;
  ID := StrToInt64(edtID.Text);
  PhoneNumber := StrToInt64(edtPhone.Text);
  Date := StrToDate(edtJoinDate.Text);

  InfoFile := TStringList.Create;
  try
    InfoFile.Add('NAME: '+Name);
    InfoFile.Add('SURNAME: '+Surname);
    InfoFile.Add('ID NUMBER: '+IntToStr(ID));
    InfoFile.Add('PHONE NUMBER: '+IntToStr(PhoneNumber));
    InfoFile.Add('DATE JOINED :'+DateToStr(Date));
    InfoFile.Add('');         // Spacers to separate next set of details
    InfoFile.Add('');

    FS := TFileStream.Create('C:\Users\GrassMan\Desktop\InfoSaver\imfofile.txt', fmOpenWrite);
    try
      FS.Seek(0, soEnd);
      InfoFile.SaveToStream(FS);
    finally
      FS.Free;
    end;
  finally
    InfoFile.Free;
  end;
end;

Comments

0

You should use TFileStream:

var
  recordStr: string;
  fs: TFileStream;
  fsFlags: Word;
  filePath: string;
begin
  filePath := 'C:\Users\GrassMan\Desktop\InfoSaver\imfofile.txt';

  recordStr := 'NAME: '+ Name + #13#10 +
               'SURNAME: '+ Surname + #13#10 +
               'ID NUMBER: '+ IntToStr(ID) + #13#10 +
               'PHONE NUMBER: '+ IntToStr(PhoneNumber) + #13#10 +
               'DATE JOINED :' + DateToStr(Date) + #13#10 +
               #13#10#13#10; // Spaces to separate next set of details

  // open if exists, create if not
  fsFlags := fmOpenWrite;
  if (not FileExists(filePath)) then
    fsFlags := fsFlags or fmCreate;

  try
    fs := TFileStream.Create(filePath);
    try
      fs.Seek(0, soEnd); // go to the end of the file

      fs.Write(recordStr[1], Length(recordStr));
    finally
      fs.Free;
    end;
  except on ex: Exception do
    begin
      ShowMessage('Error while writing to the file: ' + ex.Message);
    end;
  end;
end;  

3 Comments

fs.Position := fs.Size involves three seek operations. Better to use fs.Seek(0, soEnd) instead. And you can use a TStringList, just use its SaveToStream() method.
I think it is easier and more efficient to write a string instead of creating TStringList only for this purpose.
There is nothing wrong with using a TStringList to build up a delimited string. There is nothing wrong with building up a delimited string manually. That is a matter of personal choice. Both work.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.