0
votes

My task is to create a program which would take a text file as an input and write out all the words starting with 'a' to another one. The best solution I can come up with is as follows:

program project1;

var
  f,g:text;
  ch,b:char;
  ile,pos1,pos2,i:integer;
  s:string;

begin
    assign(f, 'input.txt');
    assign(g, 'score.txt');    
    reset(f);
    rewrite(g);
    ile:=0;
    pos1:=0; pos2:=0;
    while not eof(f) do begin
     read(f,b);
     write(g,b);
     Inc(pos1);
     read(f,ch);
     write(g,ch);
     Inc(pos2);
     if (b=' ') and (ch='a') then begin
     repeat
      read(f,ch);
      inc(pos2);
      write(g,'ala');
      until ch=' ';

     //for i:=pos1 to pos2 do
     //writeln(g,s[i]);
     //writeln;
     end;
    end;
    close(f);
    close(g);
  end.           

When I run this it reproduces the contents of input.txt and places them in score.txt. I added random statement in my 'if condition' so I could see whether it ever evaluated to true and it turned out it didn't. Could you please come up with any clue what I'm doing wrong or maybe some solution?

EDIT

I tried to experiment by using the simplest example - I made an input.txt consisting of just one word, say 'export' and changed 'if condition' to :

 if (b='e') and (ch='x') then begin
     repeat
      write(g,ch);
      read(f,ch);
      until ch='t';

My understanding is it should produce an output.txt consisting of just one word : 'export' but it seems to go into an infinite loop creating thousands of random characters in my output file...

2
Maybe all I need is some explanation of mechanics of such procedures. - Pasato
My suggestion would be to not read individual chars from your input.txt. Read it line by line using readln(f, s). Then you can scan your string s (for example with the pos() function) for words starting with an "a" or "A". If the char before the "a" is space or position is 1 you can copy it until the next space or until you have reached the end of this string. If you must read it char by char then you will need a flag (boolean) to keep track if you are in copy to score.txt mode or not. Also take in account that you are also reading the end of line chars (#10 and #13). - ToonVo
Thx ToonVo. I tried to do it using strings but it didn't work properly. Could you provide some code? Moreover pos() gives us the position of a first 'a' in the line. What if there are more words starting with 'a' in the same line? - Pasato
The idea is to use the "search and destroy" method. This means that once you have found you "a" and processed it you remove that part from the string. For example: p = pos('a', s) results in p=3 then you would destroy that part by using the copy function s = copy(s, start, number of chars) - ToonVo

2 Answers

1
votes

Thanks for all your help. I finally made by reading strings and chars simultaneously. Seems to be working properly :)

program project1;


var
  a,b:char;
  f,g:text;
  i,j,ile:integer;
  s:string;
  ok:boolean;
  begin
    assign(f,'tekst.txt');
    assign(g,'wyniks.txt');
    reset(f); rewrite(g);

    repeat
    readln(f,s);
    i:=1;
    while i<= length(s) do begin
      a:=s[i];
      b:=s[i+1];
    if (a=' ')  and (b='a') then begin
       repeat
      write(g,b);
      i:=i+1;
      b:=s[i+1];
      until b=' ';
      i:=i-1;
      writeln(g);
      end;

    i:=i+1;



    end;

    until eof(f);

  close(f);close(g);
  end.
0
votes

I'm going to show you the most important part of what you need to write: it's called a tokeniser; this is a simple version of a routine which appears in compilers. It returns the next token (in this case, the next word, but in a compiler it could also be a number) from the input line.

Function NextToken: string; // variable 'line' is global to this function
var
 space: integer;

begin
 space:= pos (' ', line);
 if space = 0 then 
  begin
   result:= line;
   line:= ''
  end
 else  
  begin
   result:= copy (line, 1, space - 1);
   line:= copy (line, space + 1, length (line) - space);
  end;
end;