Pascal read file question

Discussion in 'Mac Programming' started by larswik, Mar 22, 2011.

  1. larswik macrumors 68000

    Joined:
    Sep 8, 2006
    #1
    Hello, Last week I could not make it to the Lab to do my homework. It is due tomorrow and I thought I would write it in Xcode since I have the Pascal stuff installed. Then tomorrow take in a jump drive and transfer it to their computers and print it out and turn it in. In class we read in a text file that the instructor gives us. I am trying to recreate it on my machine but it can't find the file? Then tomorrow I will redirect it to find the instructors file to process the correct numbers.
    Code:
    program readfile;
       uses
         EmptyPlaceHolderUnit;
    
       var
          f : text;
    	  number : integer;
    
    begin
    assign(f,'num.rtf');
    reset(f);
    
    while NOT EOF(f) do
    	readln(f, number);
    	
    writeln('The item was: ', number);
    	
    end.
    I created a simple text file called num.rtf and placed it in the root directory thinking it would start to look for the file there. It is not seeing it. Any ideas would would be great.

    In short where does pascal in xCode start looking for text files to read in?

    Thanks

    -Lars
     
  2. Bill McEnaney macrumors 6502

    Joined:
    Apr 29, 2010
    #2
    I don't know, Lars. But why not specify the path to your text file? If the file is in your home directory, you could write, "assign(f, '$HOME/num.rtf');"
     
  3. larswik thread starter macrumors 68000

    Joined:
    Sep 8, 2006
    #3
    Hi Bill, thanks for the late night response. I tried your idea and I get this when I compile

    I placed the file in my 'Macintosh HD' where the Application, library folders are. Here is what it looks like with your sample code to make sure I am doing it right.

    Code:
    program readfile;
       uses
         EmptyPlaceHolderUnit;
    
       var
          f : text;
    	  number : integer;
    
    begin
    assign(f, '$HOME/num.rtf');
    reset(f);
    
    while NOT EOF(f) do
    	readln(f, number);
    	
    writeln('The item was: ', number);
    	
    end.
    I am guessing it is going to start looking in the root drive first?
     
  4. jiminaus macrumors 65816

    jiminaus

    Joined:
    Dec 16, 2010
    Location:
    Sydney
    #4
    If I can jump in quickly. The computer won't "search" for the file anywhere. It will only look where you tell it. If you're putting the input file in the Macintosh HD folder then just use "/num.rtf".

    If you want to use "$HOME/num.rtf" move the input file into your home folder where your Desktop and Documents folders are. But I don't know if your Pascal library will expand $HOME. I think it might take it literally and look for the file in a directory name $HOME in what ever the current working directory is.
     
  5. larswik thread starter macrumors 68000

    Joined:
    Sep 8, 2006
    #5
    Ahhh! some success! I typed in "/num.rtf" and now I got a different error code.

    Code:
    EInOutError : Invalid input
      $0000223F  PASCALMAIN,  line 14 of /Work in Progress/Pascal/test_read/read/read.pas
    I simply typed the number '15' in and saved it trying to get it to read it. Now I just need to find out why it won't except the integer 15 when I defined the variable that it shold be placed in to be of type integer?

    -Lars
     
  6. larswik thread starter macrumors 68000

    Joined:
    Sep 8, 2006
    #6
    I got it working. For some reason it would bot except the file 'num.rtf' that I created with text editor. I opened up Word and saved it as nums.txt and it worked fine!

    First time opening a file!!

    Thanks for the push in the right direction!

    -Lars
     
  7. jiminaus, Mar 23, 2011
    Last edited: Mar 23, 2011

    jiminaus macrumors 65816

    jiminaus

    Joined:
    Dec 16, 2010
    Location:
    Sydney
    #7
    That makes sense, one of the dangers of using Word to create input files. I couldn't replicate your problem, now I know why.

    BTW There is a bug in your code in that it will only display the last number in the file. But I'll leave that for you. Unless of course that's what you intend. :D

    Also in case it ever comes up as being import you can find out where the executable is being run from using a program like the following:

    Code:
    Program Example29;
    
    { Program to demonstrate the GetDir function. }
    
    Var S : String;
    
    begin
      GetDir (0,S);
      Writeln ('Current directory is : ',S);
    end.
    
    (courtesy of the FreePascal documentation www.freepascal.org/docs-html/rtl/system/getdir.html)
     
  8. larswik thread starter macrumors 68000

    Joined:
    Sep 8, 2006
    #8
    Thanks again. The Lab assignment is to read in 6 numbers or pressures and identify the highest, lowest and the average of the pressures.

    I wrote down 6 numbers in the txt document but it always said "low = 0" and "High = 1400". I never wrote a 0 as one of the numbers. When I ran the debugger I noticed that after it read my last number it went through the loop 1 more time and retrieved the number '0' which I never added. I am guessing it is reading in the terminator as a value?

    Here is the code and file so far.
    Code:
    program Pressure;
       uses
         EmptyPlaceHolderUnit;
    	 
       var
          sample,low, high, average: integer;
    	  myfile : text;
    	  
    Procedure test_low_high (S :integer; var L,H,A : integer);
    
    begin
    	if (S < L)
    	 then L := S	 
    	else
    	if (S > H)
    	 then H := S
    	  
    end;
    
    begin
    
    sample := 0;
    low := maxint;
    high := -maxint;
    average := 0;
    
    assign(myfile, '/nums.txt');
    reset(myfile);
    
    while NOT EOF (myfile) OR EOLN do
    begin
    	READ(myfile, sample);
        test_low_high(sample, low, high, average);
    end;
    
    writeln('low= ', low, ' high= ', high);
    writeln;
    
    end.
    Strange? Do you think it is seeing a terminator?
     

    Attached Files:

    • nums.txt
      File size:
      27 bytes
      Views:
      41
  9. jiminaus macrumors 65816

    jiminaus

    Joined:
    Dec 16, 2010
    Location:
    Sydney
    #9
    There is a problem in the logic of your while which causing you to read past the end of the file and resulting in sample being assigned to zero.

    Firstly your checking EOLN condition of standard input and not of your input file.

    Secondly you've code to keep looping while either of these two things is true: a) it's not the end of file; or b) it is the end of the line. This is not what you want.
     
  10. larswik thread starter macrumors 68000

    Joined:
    Sep 8, 2006
    #10
    Yes, I did see that mistake after I posted of course :)I almost have it. The whole project is to read in 4 different intervals of 6 pressure numbers and write them to the screen. I got it kind of working. It reads in the first line of information from the nums.txt document. But it reaches EOF before it reads in the second line of data from the TXT file?

    Code:
    program Pressure(input, output);
       uses
         EmptyPlaceHolderUnit;
    	 
       var
          sample,low, high, average, count: integer;
    	  myfile : text;
    	  
    Procedure test_low_high (S, C :integer; var L,H,A : integer);
    
    begin
    	if (S < L)
    	 then L := S	 
    	else
    	if (S > H)
    	 then H := S;
    	 
    	 A := A + S;
    	 write (' |',S:1);
    end;
    
    begin
    
    sample := 0;
    low := maxint;
    high := -maxint;
    average := 0;
    count := 1;
    
    assign(myfile, '/nums.txt');
    reset(myfile);
    
    while NOT EOF (myfile)  do
    begin
    	write(count,')');
    	while NOT EOLN (myfile) do
    		begin
    		READ(myfile, sample);
    		test_low_high(sample, count, low, high, average);
    	end;
    	count := count + 1;
    	writeln;
    	readln(myfile, sample);
    end;
    average := average DIV count;
    writeln;
    writeln('low= ', low, ' high= ', high);
    writeln('Average is ', average);
    writeln('Count is ', count);
    writeln;
    
    end.
    
    I am stumped as to why it won't see the second line. It looks like it starts because it write to the screen '2)' but the rest is blank. I included the txt file.

    Thanks again for your help.

    -Lars
     

    Attached Files:

    • nums.txt
      File size:
      54 bytes
      Views:
      45
  11. jiminaus, Mar 23, 2011
    Last edited: Mar 23, 2011

    jiminaus macrumors 65816

    jiminaus

    Joined:
    Dec 16, 2010
    Location:
    Sydney
    #11
    You need to read past the EOL, which I think you know, but you can't do that with a read, you need a readln.

    Add a dummy string variable and change the read(myfile, sample) just before the end of the outer while loop to readln(myfile, dummy).

    Your input file has a stray comma at the end of line 2 which caused your program to crash. It also has some extra trailing blank lines which is causing your program to read extraneous lines.

    EDIT: Sorry I misread your code, you were actually using readln. It seems you needed to readln into a string variable instead of an integer variable to read past the EOL.
     
  12. Bill McEnaney macrumors 6502

    Joined:
    Apr 29, 2010
    #12
    You're welcome, Lars. I'm happy to help you, another programmer.

    Maybe I should have told everybody that, if your file were in you your home directory, "$HOME/nums.txt" would tell the computer to look there for it. The HOME variable holds the path to the directory you'll enter automatically when you open a Terminal window. For example, the value of my HOME variable is "/Users/Bill".
     
  13. larswik thread starter macrumors 68000

    Joined:
    Sep 8, 2006
    #13
    Thanks guys.

    jiminaus - I added the comma to the end as a test. When it read in the line it would read in an extra '0' which I never wrote in the list. It seemed like it was reading in the terminator as a valid integer for the list. When I placed the comma their it solved the problem.

    Here is the interesting part of the class. I am reading Turbo Pascal but the instructor asked us to skip everything TURBO and just work with standard Pascal. So strings are not allowed and we skipped over that in the book.

    For this lesson he wants us to use PROCEDURES to solve this problem and only 1 variable to store the pressure value as it is evaluated as either the lowest number, highest number and then added to the sum.

    The file I included might have extra data in it because I wrote it with Word and saved it as a TXT file. I could only seem to get TextEdit to save as .RTF files which Pascal didn't like.

    -Lars
     
  14. balamw Moderator

    balamw

    Staff Member

    Joined:
    Aug 16, 2005
    Location:
    New England
    #14
    You could use Xcode or TextWrangler to create regular text files.

    (Or Format -> Make Plain Text in TextEdit :p)

    B
     
  15. larswik thread starter macrumors 68000

    Joined:
    Sep 8, 2006
    #15
    balamw - Funny, I just saw that 2 minutes ago and re saved it and it gave me the option of a .TXT file.

    Everything is working except for the fact that it won't read the second line of information from the TXT file. (I included it as an attachment) I am using a while loop to input the data.

    Code:
    program Pressure(input, output);
       uses
         EmptyPlaceHolderUnit;
    	 
       var
          sample,low, high, average, lcount, count: integer;
    	  myfile : text;
    	  
    Procedure test_low_high (S, C :integer; var L,H,A : integer);
    
    begin
    	if (S < L)
    	 then L := S	 
    	else
    	if (S > H)
    	 then H := S;
    	 
    	 A := A + S;
    	 write (' | ',S:1);
    end;
    
    begin
    
    sample := 0;
    low := maxint;
    high := -maxint;
    average := 0;
    lcount := 1;
    count := 0;
    
    assign(myfile, '/input.txt');
    reset(myfile);
    writeln('*Pressure Report*');
    while NOT EOF (myfile)  do
    begin
    	write(lcount,')');
    	while NOT EOLN (myfile) do
    		begin
    		READ(myfile, sample);
    		test_low_high(sample, count, low, high, average);
    	end;
    	readln(myfile, sample);
    	lcount := lcount + 1;
    	writeln;
    end;
    
    writeln;
    writeln('High Pressure is: ', high);
    writeln('Low Pressure is: ', low);
    writeln('Average is ', average);
    writeln('Count is ', count);
    writeln;
    
    end.
    Can you see why it is skipping the second line?
     

    Attached Files:

  16. Bill McEnaney macrumors 6502

    Joined:
    Apr 29, 2010
    #16
    Lars,

    What happens if you replace "readln(myfile, sample);" with "readln(myfile)" on the line after your inner while-loop? I'm not sure what's happening. But I think the computer is probably trying to read a value of sample from the end of the first line.

    Bill
     
  17. larswik thread starter macrumors 68000

    Joined:
    Sep 8, 2006
    #17
    Bill, you are a genius! I removed that and now it reads in all the lines from the text file.

    I need to break that down so I understand it better but it solved my issue for now.

    Thank you very much!

    -Lars
     
  18. jiminaus macrumors 65816

    jiminaus

    Joined:
    Dec 16, 2010
    Location:
    Sydney
    #18
    Whoa, standard pascal has no strings. :eek: It's been 15 years since I've coded in Pascal, and then it was Turbo Pascal. I hadn't even the slight inkling that the string type was non-standard. It seems so fundamental to a begineer's language.

    The major assignment was to develop an address book program. I blew my high school teacher away by handing in a program coded in an object-oriented style and which used TurboVision for the UI. :D
     
  19. larswik thread starter macrumors 68000

    Joined:
    Sep 8, 2006
    #19
    OK my homework assignment is now finished. All I have to do now is to take it to the Lab at the collage and use their TXT file instead of mine. The only problem with the program is that after the second time through the loop it always sees the "Low Pressure a 0". It is some how reading the terminator at the end of each line as a valid integer number.

    Final code and text file
    Code:
    program Pressure(input, output);
       uses
         EmptyPlaceHolderUnit;
    	 
       var
          sample,low, high, lcount, count: integer;
    	  average :real;
    	  myfile : text;
    	  
    Procedure test_low_high (S :integer; var C,L,H : integer; var A : real);
    
    begin
    	if (S < L)
    	 then L := S	 
    	else
    	if (S > H)
    	 then H := S;
    	 
    	 A := A + S;
    	 write (' | ',S:3);
    	 C := C + 1;
    end;
    
    begin
    
    sample := 0;
    low := maxint;
    high := -maxint;
    average := 0.0;
    lcount := 1;
    count := 0;
    
    assign(myfile, '/input.txt');
    reset(myfile);
    writeln('*Pressure Report*');
    
    while NOT EOF (myfile)  do
    begin
    	write(lcount,')');
    	while NOT EOLN (myfile) do
    		begin
    		READ(myfile, sample);
    		test_low_high(sample, count, low, high, average);
    	end;
    	readln(myfile);
    	average := average / count;
    	writeln;
    	writeln('High Pressure is: ', high);
        writeln('Low Pressure is: ', low);
        writeln('Average is: ', round(average));
        
    	if (high > 5000)
    		then writeln( 'DANGER! OVER PRESSURE ', high);
    	 
    	if (low < 14)
    		then writeln('DANGER! VACUUM ', low); 
    	
    	lcount := lcount + 1;
    	count := 0;
    	average := 0.0;
    	low := 0;
    	high := 0;
    	writeln;
    end;
    end.
    I am hoping by using their file on their Linux machine will solve this problem.

    Thanks again.

    -Lars
     

    Attached Files:

  20. Bill McEnaney macrumors 6502

    Joined:
    Apr 29, 2010
    #20
    You're welcome very much. Me? A genius? Nah, I just think like a machine. That's why people tell me I'm too rigid. :)
     
  21. Bill McEnaney macrumors 6502

    Joined:
    Apr 29, 2010
    #21
    I seem to remember that in Pascal, the string data type has always been nonstandard. At least it was nonstandard when I learned that language. So my professors suggested something like this.

    Code:
    const
       Max_String_Length = 80;
    
    type
       String_Type = packed array[0 .. Max_String_Length] of char;
    
     
  22. larswik thread starter macrumors 68000

    Joined:
    Sep 8, 2006
    #22
    So I stopped by the Lab today to transfer my code to the Linux system and test the code. After I write it and it compiles I need to print out on paper the code and the result. I thought it was going to be a slam dunk but no. I ended up rewrite the code from scratch down there. So I brought home the final code that worked down there to test it on the Mac and got an error. It looks like they are not 100% compatible. Here is the code that compiled and worked on the Linux system and the "data7.dat" file that contained the numbers.

    Code:
    program pressure(data7,out7);
    
    var
     data7, out7 :text;
     n, count : integer;
     
     procedure lowtohigh(var low, high :integer; pressure : integer);
     begin
    	if (pressure < low)
    		then low := pressure;
    		
    	if (pressure > high)
    		then high := pressure;
     end;
     
     procedure produceresults(low, high : integer; total : real);
    	begin
    	writeln(out7,'Low Pressure is: ',low:6);
    	writeln(out7,'High Pressure is: ',high:7);
    	total := total / 6;
    	writeln(out7, 'Average Pressure is: ',round(total):1);
    	if (high > 5000)
    		then writeln(out7,'*** DANGER OVER PRESSURE OF: ', high:1);
    	if (low < 14)
    		then writeln(out7,'*** DANGER VACUUME OF: ', low:7);
    	end;
     
     procedure processpressure;
     
     var 
    	pcount, pressure, high, low : integer;
    	total : real;
    	
    begin
    	total := 0;
    	high := -maxint;
    	low := maxint;
    	pcount := 1;
    
    	while pcount <= 6 do
    		begin
    			read(data7,pressure);
    			writeln (out7,'Process ',pcount:1,'  Pressure: ', pressure:1);
    			total := total + pressure;
    			lowtohigh(low, high, pressure);
    			pcount := pcount + 1;
    	
    		end;
    	produceresults(low, high, total);
    
    end;
    
    begin
    reset(data7);
    rewrite(out7);
    Read(data7, n);
    count := 0;
    
    while count < n do
    	begin
    		processpressure;
    		writeln(out7, '********************');
    		count := count + 1;
    	end;
    end.
    
    In the version down there when I compiled and ran it, the program asked me to type in the file it needed and what the output file was going to be. When I try to run it on my Mac it asks no such question for the file name to use? I used 'assign(myfile, '/input.txt');' to find the file yesterday night. but they said I could not use 'assign' because it would not work.

    O well, I will get an A since it worked right.

    Thanks!

    -Lars
     
  23. Bill McEnaney macrumors 6502

    Joined:
    Apr 29, 2010
    #23
    Congratulations, Lars.

    What Pascal compiler are you running on your Mac? Is it Free Pascal, GNU Pascal, Turbo Pascal . . .? Once we know what one you're running, it should be easy to tell what procedure you need to call instead of the "assign" procedure when your program runs on your Mac.
     
  24. balamw Moderator

    balamw

    Staff Member

    Joined:
    Aug 16, 2005
    Location:
    New England
    #24
    I would suggest the opposite.

    Find out what compiler they are using on the Linux boxes at SBCC and make sure you are using the same compiler and switches on your Mac. Even if it doesn't integrate well with Xcode. Try to use the same workflow as they do at school on your Mac.

    B
     
  25. Bill McEnaney, Mar 24, 2011
    Last edited: Mar 24, 2011

    Bill McEnaney macrumors 6502

    Joined:
    Apr 29, 2010
    #25
    That's a much better idea. But maybe Lars should know what "assign" procedure to use with each compiler he runs because he may need to write Pascal programs for either or both platforms.
     

Share This Page