Text file manipulation

Daaave 0 Tallied Votes 507 Views Share

This snippet shows how to open, read, write and close text files. This skeleton can be modified to handle any type of file, from untyped to text to typed files.

procedure CopyFile;
var
  F1  : text;
  F2  : text;
  FN1 : string;
  FN2 : string;
begin
FN1 := 'infile.txt';
FN2 := 'outfile.txt';

assign( F1, FN1 );
reset( F1 );  { open file for reading }

assign( F2, FN2 );
rewrite( F2 );  { open file for writing, destroying contents, if any }

while not EOF( F1 ) do
begin
readln( F1 );
{ file manipulation goes here }
writeln( F2 );
end;

close( F1 );
close( F2 );
end;

Dani AI

Generated

provided a neat minimal skeleton for opening, reading and writing text files; the following expands on that and answers while clarifying a misconception raised by .

read vs readln: read reads formatted items (stops at whitespace) while readln reads the remainder of the current line (or into a string variable) and moves to the next line. For copying or manipulating whole lines, read the line into a string and write that string out — that preserves line content reliably. Using the unparameterised calls in the examples does not actually transfer data; you must read into variables and write those variables.

To save the text from MEMO1 as the first column and MEMO2 as the second column, iterate to the longer of the two line counts, take an empty string when a memo has no line at that index, and write a delimiter (CSV or tab). Example (Delphi-style) — this produces a safe CSV with quoted fields:

procedure SaveMemosAsColumns(const AFileName: string; MemoLeft, MemoRight: TStrings);
var
  F: TextFile;
  i, MaxLines: Integer;
  L, R: string;
begin
  AssignFile(F, AFileName);
  Rewrite(F);
  try
    if MemoLeft.Count > MemoRight.Count then MaxLines := MemoLeft.Count else MaxLines := MemoRight.Count;
    for i := 0 to MaxLines - 1 do
    begin
      if i < MemoLeft.Count then L := MemoLeft[i] else L := '';
      if i < MemoRight.Count then R := MemoRight[i] else R := '';
      L := StringReplace(L, '"', '""', [rfReplaceAll]);
      R := StringReplace(R, '"', '""', [rfReplaceAll]);
      Writeln(F, '"' + L + '","' + R + '"');
    end;
  finally
    CloseFile(F);
  end;
end;

Troubleshooting notes: pick a delimiter that suits your consumers (tab if fields may contain commas), handle encoding explicitly (TStringList.SaveToFile with TEncoding.UTF8 on newer Delphi), and use streaming (TStreamWriter/TFileStream) for very large content. If quoted CSV is used, double embedded quotes as shown.

Yggdrasil 0 Newbie Poster

{Ohayou:: It's better I think not to write:}
readln(F1);
writeln(F2);
{but instead}
read(F1);
write(F2);
{because ..ln moves the pointer to the next line without reading or writing in the same line}

Yggdrasil 0 Newbie Poster

{Ohayou:: It's better I think not to write:}
readln(F1);
writeln(F2);
{but instead}
read(F1);
write(F2);
{because ..ln moves the pointer to the next line without reading or writing in the same line}

Deffcon 0 Newbie Poster

Umm i know it's not exactly in this context and that it's quite harder to achieve but how can i manipulate my text so that it saves the text from MEMO1 into the first column in the file i'm saving the text into and the text from MEMO2 into the same file ...second column? ...I'm looking everywhere for any hints but can't find any.
Thanks!

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.