Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

PRINT AND ERROR FILES

Status
Not open for further replies.

chriscarlile911

Technical User
Jun 12, 2003
3
0
0
GB
hi all
i'll keep this short and sweet. i now have just about finished my wages program but i'm afraid i don't know how to 'write errors to error file' or 'output to a printer'. this may also sound a bit stoopid, but how do i write '£' without getting a syntax error. do i use ascii 35 and if so, how do i insert it.
regards and thanx
chriscarlile911
 
you do what you just did: write('£'); or write(#35); you shouldnt get a syntax error.

What kind of file do you want to write to? I guess a text file would be more appropriate seeing as its only a list of errors and Im assuming its the file to be printed too.

VAR
txt_fl : text; {text is a text file variable}

...
{first time ever}
assign(txt_fl,'C:\textfile.txt');
rewrite(txt_fl);
close(txt_fl);
...

Only do that once, make it an initialization procedure. (shown below). If you do this every time, you will end up making a new blank file everytime you mean to add to an existing file...

PROCEDURE init_file;

VAR
txt_fl : text;

BEGIN
assign(txt_fl,'C:\textfile.txt');
{$I-} {turns off system interrupt}
read(txt_fl);
{$I+} {turns it back on !! needed so you dont mess up your pc}
IF IORESULT <> 0 THEN
BEGIN
rewrite(txt_fl);
close(txt_fl);
END;
END;

That'll check if the file exists or not. If it doesn't, it'll make a copy. You can run this procedure every time as it will only create a file if one doesnt exist.

OK next, adding the data.

VAR
error_value : string;

...
error_value := 'Quick code';
append(txt_fl);
writeln(txt_fl,error_value);
colse(txt_fl);
...

ALWAYS close files as soon as you possibly can. You dont want data flying all over the place corrupting files now do you? ;)
Personally, I would use a case statement for the error messages. Have e as an integer, then CASE e OF whatever and error_value = what ever you want. That way you get a consistent error value and it'll reduce code (depending).

PROCEDURE errors(e:integer VAR error_value:string);

BEGIN
CASE e OF
1 : error_value := 'Error 1';
2 : error_value := 'Error 2';
3 : error_value := 'Error 3';
END;
END;

PROCEDURE write_error(VAR txt_fl:text);

VAR
error_value : string;
{e : integer;}

BEGIN
assign(txt_fl,'C:\textfile.txt');
errors(2,error_value); {saying 2 as a constant will always show &quot;Error 2&quot; If you un comment the e variable, you could write code to determine the value of e}
append(txt_fl);
writeln(txt_fl,error_value);
close(txt_fl);
END;

What this does is assigns the file a location on disk, gives error_value a value determined by the value of e. The text file is then opened AT THE END of the file and a new line is written.

If you wanted to add the error at the top of the file, you would have to write a procedure that copies the contents of the file in to memory then make a blank file, add the new value then append the file and add the previous values held in memory. This may be safer to perform with 2 text files instead of virtual memory ;)

When using text files, you have to remember that it is just that! if you're writing more than one value on to the same line, you'll need to add spaces just like a writeln:

writeln(txt_fl,error_value,' ',date,' ',time,' ',user);

You can also use `write` but if you do, don;t forget to add a space at the end of each string added as all the strings follow directly on from each other instead of including carridge returns.

The printer stuff... hehe sorry. all i know is it USES printer and you writeln(lpt,file); or something. sorry

~*Gwar3k1*~
&quot;To the pressure, everything's just like: an illusion. I'll be losing you before long...&quot;
 
This is some really old code from my college days. we were given it to look at but TP doesnt like printing on my printer so Ive never used it

{***********************************************************************}
PROGRAM print_report;
{Program to sned a single text sting to the printer
connected to port LPT1. A form feed ejects the paper}

USES
crt,printer;
{The inclusion of the CRT unit gives access to screen function
The printer unit contains printer functions and allows the printer
to be be written to as a text file, but the printer does not need
to be assigned, opened or closed. The printer control can be acheived
by writing ASCII number (in decimal) to the printer.}

{Important Note: Care and patience is rquired when testing procedures
and functions that interact with printers. The consequences are not
always immediately apparent}

TYPE
nums=RECORD
min:INTEGER;
max:INTEGER;
END;

numfile=FILE OF nums;

{************************************************************************}
PROCEDURE InitialiseFiles(VAR reportheader:TEXT;VAR reportfooter:TEXT;VAR datafile:numfile);
VAR
ind:INTEGER;
maxmin:nums;

BEGIN
ASSIGN(reportheader,'A:HEADER.TXT');
ASSIGN(reportfooter,'A:FOOTER.TXT');
ASSIGN(datafile,'A:DATA.DAT');
{Put max and min number into the data file}
REWRITE(datafile);
SEEK(datafile,0);
FOR ind:=1 TO 2 DO
BEGIN
maxmin.min:=2;
maxmin.max:=8;
write(datafile,maxmin);
END;
CLOSE(datafile);
END;
{************************************************************************}

{************************************************************************}
PROCEDURE PrintFile(VAR thefile:TEXT);
VAR
str:STRING;
BEGIN
RESET(thefile);
WHILE NOT EOF(thefile) DO
BEGIN
readln(thefile,str);
writeln(LST,str);
write(LST,#10#13);
END;
CLOSE(thefile);

END;
{************************************************************************}

{************************************************************************}

PROCEDURE PrintReportData(VAR datafile:numfile);
VAR
ind,total,count:INTEGER;
average:REAL;
figs:nums;

BEGIN
total:=0;
count:=0;
write(LST,#10#13);
write(LST,'The Report');
write(LST,#10#13);
reset(datafile); {Contains only two records}
while (NOT EOF(datafile)) DO
BEGIN
read(datafile,figs);
write(LST,figs.min,' ',figs.max);
write(LST,#10#13);
total:=total+figs.max+figs.min;
count:=count+2;
END;
average:=total/count;
write(LST,' count = ',count);
write(LST,#10#13);
write(LST,' average = ',average:2:2);
write(LST,#10#13);
END;
{************************************************************************}

{************************************************************************}
PROCEDURE FinishPrintingReport;
BEGIN
write(LST,#10); {write line feed 10 decimal to printer}
write(LST,#13); {write carraige return 13 decimal to printer}
write(LST,#12); {write form feed 12 decimal to printer}
write(LST,#27,#69); {write reset printer, escape (dec27) End (dec 69)}
write('Press ENTER to Continue');
readln;
END;
{************************************************************************}


{*************************MainProgram************************************}
VAR
reportheader:TEXT;
reportfooter:TEXT;
datafile:numfile;

BEGIN
clrscr;
InitialiseFiles(reportheader,reportfooter,datafile);
PrintFile(reportheader);
PrintReportData(datafile);
PrintFile(reportfooter);
FinishPrintingReport;
END.
{***************************TheEnd***************************************}


~*Gwar3k1*~
&quot;To the pressure, everything's just like: an illusion. I'll be losing you before long...&quot;
 
gwar: In your &quot;init_file&quot; procedure, I think you meant:

Code:
BEGIN
  assign(txt_fl,'C:\textfile.txt');
  {$I-}  {turns off system interrupt}
    reset(txt_fl); <<<<<<<<<<<<<<<<<<<<<<<<----------
  {$I+}  {turns it back on !! needed so you dont mess up your pc}
  IF IORESULT <> 0 THEN
    BEGIN
      rewrite(txt_fl);
      close(txt_fl);
    END;
END;

Cheers,

Realm174


 
$I has nothing to do with system interrupts. It has to do with I/O error checking. Turned on, I/O errors bomb the program. Turned off they are merely returned in IOResult.
 
Three comments:

(1) LorenPechtel is absolutely right about IOresult. It's also worth remembering that IOresult returns to zero after it's been read, in the same way as doserror. If you need to use it twice, then store its value in a variable and test that twice.

(2) Reset like this is fine with text files, but if you ever do any other sort of file, you must include the size of the data unit to be written and read, e.g. reset(myfile, 1)

(3) Theoretically files can be left open in pascal because they will be closed automatically when the program ends. However, error logs are an exception to this, because almost by definition you are interested in them when the program ended unnaturally - and in this case the file may not be flushed before ending. No flush means the last line or two may go missing. It's also very important not to keep opening files without closing them, because eventually you will hit the operating system file limit, and then any attempt to open a new file will cause ioerror <> 0.
 
Instead of storing IOResult, simply read InOutRes instead. Same thing but it doesn't get wiped. Note that this will *NOT* work in Delphi, though. However, you don't really need $I- in Delphi, exceptions are so much better.

As for error logs--you need to at least flush and commit (note: Nothing in the RTL for this, you'll have to write your own) them. With questionable code I do so after ever write. The commit is needed in case you lock things up and have to reboot.
 
Its always safer to close files any way. And thanks for clearing up the $I thing. Ive always thought it was Interrupts. Oh well ;)

~*Gwar3k1*~
&quot;To the pressure, everything's just like: an illusion. I'll be losing you before long...&quot;
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top