You are on page 1of 22

File Handling

We have learned how to store information in variables for use during the execution of a
program, to store temporary, or working, information.
However, it is often necessary to store information more permanently, so that it can be
accessed again, even after the program has finished, the computer switched off etc.
examples are Pascal source code files (.pas files), word-processed documents, spreadsheets,
accounts data, booking information etc.
A common way of storing this information is to make use of disk files so we can write the
information we wish to preserve to either a floppy disk, or a hard disk, or a network disk.
Then later, we can read the information back into the program from the file to work on it
some more.

Declaring a File variable


Files in Pascal are represented using a new variable type called a file. As integers are for
whole numbers or Strings are for text, a file is for storing information about accessing a file.
For example, to declare that you wish to use a file that will store text data, you could use:var fileData : file of char;
The file of char part specifies that the file will be written as text, or character-based
information. The fileData part specifies the name of the variable.
This is a very common form of file used in file processing, so Pascal has a short-hand
version of declaring this type, called TEXT. You would declare it as follows:var fileDate : TEXT;

Opening a file to write information


In order to write information to a file, you need to perform the following steps:

Assign a filename to the file variable so we know which file to open.


Open the file this prevents anyone else from making changes to the file
whilst you are using it.
Write information to the file
Close the file this writes any unwritten information to the file, and allows
others to access it again.

Type out the following program:program File1;


uses Wincrt;
const fileName = 'C:\TEMP\STUDENTS.TXT';
var outFile : TEXT;
courseName, studentName : string;
begin
clrScr;
writeLn('What is the name of the course? ');
readLn(courseName);
writeLn;
writeLn('Enter students for course, one per line.');
writeLn('Enter a blank line to finish.');
assign(outFile, fileName);
rewrite(outFile);
writeLn(outFile, 'Course is: ',courseName);
repeat
readln(studentName);
if Length(studentName) > 0 then
writeLn(outFile, studentName);
until Length(studentName) = 0;
close(outFile);
writeLn('Students for course written to file');
readKey;
end.
The purpose of this program is to read a course title from the user, once only. A file is then
opened, and the course title is written to the file.
A list of students, one per line, is taken from the user. Each is written to the file straight after
they are typed.
When the user enters a blank line (i.e. the length of the studentName string is zero
Length(studentName)=0) the line is not written to the file, and the loop to get a list of
students' names is terminated.
So how do we achieve this?
The outFile variable will hold the details of the Text file to be opened. A file can hold only
one type of data for example, a file of integer could be used to output a list of integer
numbers to a file, but it could not then hold strings.
2

In order to specify which file is to be opened, the assign keyword is used, which takes two
parameters (i.e. items that appear in brackets straight after the keyword) the file variable,
and the filename of the file that is to be used.
For example, assign(outFile, fileName) will write to the fileName variable
('c:\temp\students.txt') using the outFile file variable.
To open the file, use the rewrite keyword with the file variable as a parameter - e.g.
rewrite(outFile).
To write some text to the file, use a variation of the write or writeLn procedures, where the
first parameter must be the file to write the text to. So instead of going to the screen, the data
is written to the text file e.g. to write the course name (as entered at the keyboard) to the
outFile file (i.e. to the c:\temp\students.txt file):- writeLn(outFile, courseName).
Finally, to close the file, once we have finished with it, we use the close procedure, passing
the file variable again e.g. close(outFile).

Exercise: Check file has written properly


Try running the above program, and type out the following data: For the course title, enter Pascal programming
For the students, enter the following, one name per line: Fred Bloggs
Joe 90
Harry Potter
Leo the Lion
Willie Shakey
Arry Aardvark
Now press the Enter key without typing anything i.e. type a blank line, to terminate
the repeatuntil loop.
Open the file using either notepad or Windows Explorer c:\temp\students.txt and see if
you can work out how the program produced the data in the text file. This also proves that
your data has been written out properly.

Exercise: Allow multiple courses to be written to the file


Make an alteration to the program, so that if the user types out the word course, then another
course is prompted for, and the following are output to the file: a blank line
The words Course is: followed by a space followed by whatever the user typed in at
the keyboard
A list of students should then be prompted for, and another list of students can be entered into
the system.
In this way, the user of the program can type in as many courses and lists of students as is
required.
Hints
You need two repeatuntil loops, one inside the other. The first loop tests to see if the word
course was entered, the second is the one already there:repeat
{ get course and write it to the file }
repeat
{ get students and write them to the file }
until (length(studentName)=0) or (studentName='course');
if courseName='course' then writeLn(outFile);
until length(studentName)=0;
You may like to write a message before the second loop begins to let the user know that not
only does enter a blank line terminate writing to the file, but entering the word course lets
them enter another course e.g.
writeLn('Enter "course" for another course.');

Opening a file to read information


Once you have written some information to a file, it is useful to be able to read it back into
your program again to make use of it.
The following program will take the student file that you created previously, read in the
course name, and for each student, print out a certificate headed with the course name and
the student name.
The program makes the assumption that you have only one course and one list of students in
the file. You could assume that writing to the file called 'PRN:' will do the trick of writing to
the printer. However, for the purposes of testing, we will save the results to a file in order to
avoid wasting lots of paper!
Type it in and run it to see what happens:program File2;
const fileName = 'C:\TEMP\STUDENTS.TXT';
4

reportName = 'C:\TEMP\REPORT.TXT';
var inFile, outFile : TEXT;
courseName, studentName : string;
begin
assign(inFile, fileName); reset(inFile);
assign(outFile, reportName); rewrite(outFile);
readLn(inFile, courseName);
courseName:=copy(courseName,12,255);
while not eof (inFile) do
begin
readLn(inFile,studentName);
writeLn(outFile, 'CERTIFICATE OF COURSE ATTENDANCE');
writeLn(outFile, '--------------------------------');
writeLn(outFile);
writeLn(outFile,'This certifies that ',studentName);
write(outFile,'has completed the course: ');
writeLn(outFile,courseName);
writeLn(outFile); writeLn(outFile); writeLn(outFile);
writeLn(outFile,' Signed _________ (Facilitator)');
writeLn(outFile);
writeLn(outFile, '================================');
writeLn(outFile); writeLn(outFile); writeLn(outFile);
end;
close(outFile); close(inFile);
end.
This program produces no screen output its functionality is purely dealing in processing
files. Note that this is a very common function in businesses this type of program is
commonly used to process data overnight.
You can see that opening a file is a similar process to writing to a file. You use the assign
procedure to assign a filename to read data from, and link that to a file variable.
Instead of using the rewrite procedure (which writes to the file), use the reset procedure,
which effectively resets the file pointer to start reading from the beginning of the file.
To close the file once you have finished reading from it, use the close procedure as for
writing to files.
Finally, to read lines of text from the file, use the readLn procedure, which reads a line of
text from the text file, up to the end of the line. The parameters for readLn are the same as
for reading text from the keyboard, except the first parameter should be the file variable so
the structure is similar to writeLn.

Exercise: Check report file has written properly


Try running the above program, and type out the following data:Open the file using either notepad or Windows Explorer c:\temp\report.txt and see if
you can work out how the program produced the data in the text file. This also proves that
your data has been written out properly.
Exercise: Create a satisfaction survey for each student
Alter the program File2, so that it also creates a file called c:\temp\survey.txt and writes to
it the following information for each student:COURSE SURVEY
------------Course: Course name
Name: Name of Student
Could you take a few moments to
complete this survey:[ ] Did you find the course useful?
[ ] Would you recommend it?
[ ] Should the tutor get a life?
Thank you for your time.
================================

Hint: You will need to create a new file variable (e.g. surveyFile : Text), assign it a new
constant name, rewrite it to write to it, and use the WriteLn and Write commands to write
to the file. Finally, you will need to close the file.
For example, write("Course: "); writeLn(courseName);

As a light aside, here's a few excerpts from IT professionals and some of their experiences
dealing with less-than-IT-literate users:About a month ago I received a support call from a user who claimed to be having trouble
with her new scanner. Apparently a member of our support team had installed it while she
was at lunch and it "just didn't scan anything." After asking her if it was powered along with
the usual check-outs, I told her to start the scan program and click on scan in an attempt
6

to scan in a test page. No luck. She said she could hear it working but the image it produced
was black. I decided I would be better off seeing the situation for myself and told her "I'd be
right up." She agreed and said she would continue to try and make it work herself while she
waited. When I arrived at her office the problem was immediately apparent. Picture the scene
yourself: a very frustrated young woman pressing a magazine cover firmly against the
monitor in total confusion. I did my best to contain the evil pleasure I took while explaining
to her the proper workings of her new flatbed scanner. Jason K.
I had a user ask me for a floppy to back-up a file off of her hard drive. She then asked where
to insert the floppy. I told her to insert it into the small slot that's about the same size as the
disk itself. Unfortunately for me, I was unaware she had an external Zip drive. She decided
to ram the floppy into the Zip drive as far as it would go. She then called me asking why she
couldn't read anything off the floppy. -Mike P.
I was working tech support for a major corporate-level printer manufacturer and received a
call from a user complaining that her printer was smearing toner all over the page. In fact,
she told me, in the three months she had it, it's always done that. My first thought was that
the envelope levers were flipped, so I had her open the left side of the printer to look. I asked
her, "do you see the small gray levers under the big blue levers?" "No," she replied. "Are
they behind this orange thing that says 'remove this?'" And of course her next question was,
"should I remove it?" -Warren H.
I work for a holding company that supports several hundred employees. One day I get a call
that a user's mouse is no longer working. I run through the normal battery of tests (Have you
moved your computer, possibly unplugging the mouse, etc.). After having her check
everything I could think of I thought I should personally examine the situation. As I
approached her desk she says "see my little arrow won't move". I tried to hold back my
laughter and instructed her to let go of her stapler and use the mouse instead. Another
satisfied customer. -Jack A.

FurtherinFileHandlinginC
We frequently use files for storing information which can be processed by our programs. In order to
store information permanently and retrieve it we need to use files.
Files are not only used for data. Our programs are also stored in files.
The editor which you use to enter your program and save it, simply manipulates files for you.
The Unix commands cat, cp, cmp are all programs which process your files.
In order to use files we have to learn about File I/O i.e. how to write information to a file and how
to read information from a file.
We will see that file I/O is almost identical to the terminal I/O that we have being using so far.
The primary difference between manipulating files and doing terminal I/O is that we must specify in
our programs which files we wish to use.
7

As you know, you can have many files on your disk. If you wish to use a file in your programs, then
you must specify which file or files you wish to use.
Specifying the file you wish to use is referred to as opening the file.
When you open a file you must also specify what you wish to do with it i.e. Read from the file,
Write to the file, or both.
Because you may use a number of different files in your program, you must specify when reading
or writing which file you wish to use. This is accomplished by using a variable called a file pointer.
Every file you open has its own file pointer variable. When you wish to write to a file you specify
the file by using its file pointer variable.
You declare these file pointer variables as follows:
FILE *fopen(), *fp1, *fp2, *fp3;
The variables fp1, fp2, fp3 are file pointers. You may use any name you wish.
The file <stdio.h> contains declarations for the Standard I/O library and should always be included
at the very beginning of C programs using files.
Constants such as FILE, EOF and NULL are defined in <stdio.h>.
You should note that a file pointer is simply a variable like an integer or character.
It does not point to a file or the data in a file. It is simply used to indicate which file your I/O
operation refers to.
A file number is used in the Basic language and a unit number is used in Fortran for the same
purpose.
The function fopen is one of the Standard Library functions and returns a file pointer which you use
to refer to the file you have opened e.g.
fp = fopen( prog.c, r) ;
The above statement opens a file called prog.c for reading and associates the file pointer fp with
the file.
When we wish to access this file for I/O, we use the file pointer variable fp to refer to it.
You can have up to about 20 files open in your program - you need one file pointer for each file you
intend to use.
File I/O
The Standard I/O Library provides similar routines for file I/O to those used for standard I/O.
8

The routine getc(fp) is similar to getchar()


and putc(c,fp) is similar to putchar(c).
Thus the statement
c = getc(fp);
reads the next character from the file referenced by fp and the statement
putc(c,fp);
writes the character c into file referenced by fp.
/* file.c: Display contents of a file on screen */
#include <stdio.h>
void main()
{
FILE *fopen(), *fp;
int c ;
fp = fopen( prog.c, r );
c = getc( fp ) ;
while ( c != EOF )
{
putchar( c );
c = getc ( fp );
}
fclose( fp );
}
In this program, we open the file prog.c for reading.
We then read a character from the file. This file must exist for this program to work.
If the file is empty, we are at the end, so getc returns EOF a special value to indicate that the end of
file has been reached. (Normally -1 is used for EOF)
The while loop simply keeps reading characters from the file and displaying them, until the end of
the file is reached.
The function fclose is used to close the file i.e. indicate that we are finished processing this file.
We could reuse the file pointer fp by opening another file.
This program is in effect a special purpose cat command. It displays file contents on the screen, but
only for a file called prog.c.
By allowing the user enter a file name, which would be stored in a string, we can modify the above
to make it an interactive cat command:
9

/* cat2.c: Prompt user for filename and display file on screen */


#include <stdio.h>
void main()
{
FILE *fopen(), *fp;
int c ;
char filename[40] ;
printf(Enter file to be displayed: );
gets( filename ) ;
fp = fopen( filename, r);
c = getc( fp ) ;
while ( c != EOF )
{
putchar(c);
c = getc ( fp );
}
fclose( fp );
}
In this program, we pass the name of the file to be opened which is stored in the array called
filename, to the fopen function. In general, anywhere a string constant such as prog,c can be used
so can a character array such as filename. (Note the reverse is not true).
The above programs suffer a major limitation. They do not check whether the files to be used exist
or not.
If you attempt to read from an non-existent file, your program will crash!!
The fopen function was designed to cope with this eventuality. It checks if the file can be opened
appropriately. If the file cannot be opened, it returns a NULL pointer. Thus by checking the file
pointer returned by fopen, you can determine if the file was opened correctly and take appropriate
action e.g.
fp = fopen (filename, r) ;
if ( fp == NULL)
{
printf(Cannot open %s for reading \n, filename );
exit(1) ; /*Terminate program: Commit suicide !!*/
}
The above code fragment show how a program might check if a file could be opened appropriately.
The function exit() is a special function which terminates your program immediately.
10

exit(0) mean that you wish to indicate that your program terminated successfully whereas a nonzero
value means that your program is terminating due to an error condition.
Alternatively, you could prompt the user to enter the filename again, and try to open it again:
fp = fopen (fname, r) ;
while ( fp == NULL)
{
printf(Cannot open %s for reading \n, fname );
printf(\n\nEnter filename : );
gets( fname );
fp = fopen (fname, r) ;
}
In this code fragment, we keep reading filenames from the user until a valid existing filename is
entered.
Exercise:
Modify the above code fragment to allow the user 3 chances to enter a valid
filename. If a valid file name is not entered after 3 chances, terminate the program.
RULE: Always check when opening files, that fopen succeeds in opening the files
appropriately.
Obeying this simple rule will save you much heartache.
Example 1: Write a program to count the number of lines and characters in a file.
Note: Each line of input from a file or keyboard will be terminated by the newline character \n.
Thus by counting newlines we know how many lines there are in our input.

11

/*count.c : Count characters in a file*/


#include <stdio.h>
void main()
/* Prompt user for file and count number of characters
and lines in it*/
{
FILE *fopen(), *fp;
int c , nc, nlines;
char filename[40] ;
nlines = 0 ;
nc = 0;
printf(Enter file name: );
gets( filename );
fp = fopen( filename, r );
if ( fp == NULL )
{
printf(Cannot open %s for reading \n, filename );
exit(1);
/* terminate program */
}
c = getc( fp ) ;
while ( c != EOF )
{
if ( c == \n )
nlines++ ;
nc++ ;
c = getc ( fp );
}
fclose( fp );
if ( nc != 0 )
{
printf(There are %d characters in %s \n, nc, filename );
printf(There are %d lines \n, nlines );
}
else
printf(File: %s is empty \n, filename );
}

Example 2: Write a program to display file contents 20 lines at a time. The program pauses after
displaying 20 lines until the user presses either Q to quit or Return to display the next 20 lines. (The
Unix operating system has a command called more to do this ) As in previous programs, we read
the filename from user and open it appropriately. We then process the file:
12

read character from file


while not end of file and not finished do
begin
display character
if character is newline then
linecount = linecount + 1;
if linecount == 20 then
begin
linecount = 1 ;
Prompt user and get reply;
end
read next character from file
end
/* display.c: File display program */
/* Prompt user for file and display it 20 lines at a time*/
#include <stdio.h>
void main()
{
FILE *fopen(), *fp;
int c , linecount;
char filename[40], reply[40];
printf(Enter file name: );
gets( filename );
fp = fopen( filename, r );

/* open for reading */

if ( fp == NULL )
/* check does file exist etc */
{
printf(Cannot open %s for reading \n, filename );
exit();
/* terminate program */
}
linecount = 1 ;
reply[0] = \0 ;
c = getc( fp ) ;
/* Read 1st character if any */
while ( c != EOF && reply[0] != Q && reply[0] != q)
{
putchar( c ) ;
/* Display character */
if ( c == \n )
linecount = linecount+ 1 ;
13

if ( linecount == 20 )
{
linecount = 1 ;
printf([Press Return to continue, Q to quit]);
gets( reply ) ;
}
c = getc ( fp );
}
fclose( fp );
}
The string reply will contain the users response. The first character of this will be reply[0]. We
check if this is q or Q. The brackets [] in printf are used to distinguish the programs message
from the file contents.
Example 3: Write a program to compare two files specified by the user, displaying a message
indicating whether the files are identical or different. This is the basis of a compare command
provided by most operating systems. Here our file processing loop is as follows:
read character ca from file A;
read character cb from file B;
while ca == cb and not EOF file A and not EOF file B
begin
read character ca from file A;
read character cb from file B;
end
if ca == cb then
printout(Files identical);
else
printout(Files differ);
This program illustrates the use of I/O with two files. In general you can manipulate up to 20 files,
but for most purposes not more than 4 files would be used. All of these examples illustrate the
usefulness of processing files character by character. As you can see a number of Operating System
programs such as compare, type, more, copy can be easily written using character I/O. These
programs are normally called system programs as they come with the operating system. The
important point to note is that these programs are in no way special. They are no different in nature
than any of the programs we have constructed so far.
/* compare.c : compare two files */
#include <stdio.h>
void main()
{
FILE *fp1, *fp2, *fopen();
int ca, cb;
char fname1[40], fname2[40] ;
14

printf(Enter first filename:) ;


gets(fname1);
printf(Enter second filename:);
gets(fname2);
fp1 = fopen( fname1, r );
/* open for reading */
fp2 = fopen( fname2, r ) ; /* open for writing */
if ( fp1 == NULL )
/* check does file exist etc */
{
printf(Cannot open %s for reading \n, fname1 );
exit(1); /* terminate program */
}
else if ( fp2 == NULL )
{
printf(Cannot open %s for reading \n, fname2 );
exit(1); /* terminate program */
}
else
/* both files opened successfully */
{
ca = getc( fp1 ) ;
cb = getc( fp2 ) ;
while ( ca != EOF && cb != EOF && ca == cb )
{
ca = getc( fp1 ) ;
cb = getc( fp2 ) ;
}
if ( ca == cb )
printf(Files are identical \n);
else if ( ca != cb )
printf(Files differ \n );
fclose ( fp1 );
fclose ( fp2 );
}
}
Writing to Files
The previous programs have opened files for reading and read characters from them.
To write to a file, the file must be opened for writing e.g.
fp = fopen( fname, w );
If the file does not exist already, it will be created. If the file does exist, it will be overwritten! So,
be careful when opening files for writing, in case you destroy a file unintentionally. Opening files
for writing can also fail. If you try to create a file in another users directory where you do not have
access you will not be allowed and fopen will fail.
Character Output to Files
The function putc( c, fp ) writes a character to the file associated with the file pointer fp.
Example:
Write a file copy program which copies the file prog.c to prog.old
15

Outline solution:
Open files appropriately
Check open succeeded
Read characters from prog.c and
Write characters to prog.old until all characters
Close files

copied

The step: Read characters .... and write .. may be refined to:
read character from prog.c
while not end of file do
begin
write character to prog.old
read next character from prog.c
end
/* filecopy.c : Copy prog.c to prog.old */
#include <stdio.h>
void main()
{
FILE *fp1, *fp2, *fopen();
int c ;
fp1 = fopen( prog.c, r );
/* open for reading */
fp2 = fopen( prog.old, w ) ; ../* open for writing */
if ( fp1 == NULL )
/* check does file exist etc */
{
printf(Cannot open prog.c for reading \n );
exit(1); /* terminate program */
}
else if ( fp2 == NULL )
{
printf(Cannot open prog.old for writing \n);
exit(1); /* terminate program */
}
else
/* both files O.K. */
{
c = getc(fp1) ;
while ( c != EOF)
{
putc( c, fp2); /* copy to prog.old */
c = getc( fp1 ) ;
}
fclose ( fp1 );
/* Now close files */
fclose ( fp2 );
printf(Files successfully copied \n);
}}
16

The above program only copies the specific file prog.c to the file prog.old. We can make it a general
purpose program by prompting the user for the files to be copied and opening them appropriately.
/* copy.c : Copy any user file*/
#include <stdio.h>
void main()
{
FILE *fp1, *fp2, *fopen();
int c ;
char fname1[40], fname2[40] ;
printf(Enter source file:) ;
gets(fname1);
printf(Enter destination file:);
gets(fname2);
fp1 = fopen( fname1, r );
/* open for reading */
fp2 = fopen( fname2, w ) ; ../* open for writing */
if ( fp1 == NULL )
/* check does file exist etc */
{
printf(Cannot open %s for reading \n, fname1 );
exit(1); /* terminate program */
}
else if ( fp2 == NULL )
{
printf(Cannot open %s for writing \n, fname2 );
exit(1); /* terminate program */
}
else
/* both files O.K. */
{
c = getc(fp1) ;
/* read from source */
while ( c != EOF)
{
putc( c, fp2); /* copy to destination */
c = getc( fp1 ) ;
}
fclose ( fp1 );
/* Now close files */
fclose ( fp2 );
printf(Files successfully copied \n);
}
}

17

CommandLineParameters:Argumentstomain()
Accessing the command line arguments is a very useful facility. It enables you to provide
commands with arguments that the command can use e.g. the command
% cat prog.c
takes the argument "prog.c" and opens a file with that name, which it then displays. The command
line argumenst include the command name itself so that in the above example, "cat" and "prog.c"
are the command line arguments. The first argument i.e. "cat" is argument number zero, the next
argument, "prog.c", is argument number one and so on.
To access these arguments from within a C program, you pass parameters to the function main().
The use of arguments to main is a key feature of many C programs.
The declaration of main looks like this:
int main (int argc, char *argv[])
This declaration states that
1.
2.
3.

main returns an integer value (used to determine if the program terminates successfully)
argc is the number of command line arguments including the command itself i.e argc must
be at least 1
argv is an array of the command line arguments

The declaration of argv means that it is an array of pointers to strings (the command line
arguments). By the normal rules about arguments whose type is array, what actually gets passed to
main is the address of the first element of the array. As a result, an equivalent (and widely used)
declaration is:
int main (int argc, char **argv)
When the program starts, the following conditions hold true:
o argc is greater than 0.
o argv[argc] is a null pointer.
o argv[0], argv[1], ..., argv[argc-1] are pointers to strings
with implementation defined meanings.
o argv[0] is a string which contains the programs name, or is an
empty string if the name isnt available. Remaining members of
argv are the programs arguments.
Example: print_args echoes its arguments to the standard output is a form of the Unix echo
command.

18

/* print_args.c: Echo command line arguments */


#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
int i = 0 ;
int num_args ;
num_args = argc ;
while( num_args > 0)
{
printf(%s\n, argv[i]);
i++ ;
num_args--;
}
}
If the name of this program is print_args, an example of its execution is as follows:
% print_args hello goodbye solong
print_args
hello
goodbye
solong
%
Exercise: Rewrite print_args so that it operates like the Unix echo command. Hint: You only need
to change the printf statement.
The following is a version of the Unix cat command:
/* cat1.c: Display files specified as command line parameters */
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
int i = 1 ;
int c ;
int num_args = 0 ;
FILE *fp;
if ( argc == 1 )
{
fprintf(stderr, "No input files\nUsage: % cat file\n");
exit(1);
}
19

if ( argc > 1 )
printf("%d files to be displayed\n", argc-1);
num_args = argc - 1;
while( num_args > 0)
{
printf("[Displaying file %s]\n", argv[i]);
num_args--;
fp = fopen( argv[i], "r" ) ;
if ( fp == NULL )
{
fprintf(stderr,"Cannot display %s \n", argv[i]);
continue; /* Goto next file in list */
}
c = getc(fp) ;
while ( c != EOF )
{
putchar( c );
c = getc( fp );
}
fclose( fp );
printf("\n[End of %s]\n--------------\n\n", argv[i]);
i++;
}
}
Note: The continue statement causes the current iteration of the loop to stop and control to return to
the loop test.
The following is a version of the Unix wc command called count which operates as follows
% count prog.c
prog.c: 300 characters 20 lines
% count l prog.c
prog.c: 20 lines
% count w prog.c
prog.c: 300 characters
/*count.c : Count lines and characters in a file */
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
int c , nc, nlines;
char filename[120];
FILE *fp, *fopen();
20

if ( argc == 1 )
{
fprintf(stderr, "No input files\n");
fprintf(stderr, "Usage: \% count [-l] [w] file\n");
exit(1);
}
nlines = 0 ;
nc = 0;
if ((strcmp("-l", argv[1]) == 0) ||
(strcmp("-w", argv[1]) == 0) )
strcpy(filename, argv[2]) ;
else
strcpy(filename, argv[1]);
fp = fopen( filename, "r" );
if ( fp == NULL )
{
fprintf(stderr,"Cannot open %s\n", filename );
exit(1);
}
c = getc( fp ) ;
while ( c != EOF )
{
if ( c == '\n')
nlines++ ;
nc++ ;
c = getc ( fp );
}
fclose( fp );
if ( strcmp(argv[1], "-w") == 0 )
printf("%s: %d characters \n", filename, nc );
else if ( strcmp(argv[1], "-l") == 0 )
printf("%s: %d lines \n", filename, nlines );
else
printf("%s: %d characters %d lines\n", filename, nc, nlines );
Logical OR is represented by || in the code above. Logical AND is represented by && in C.
The function strcpy() is one of many library string handling functions. It takes two strings as
arguments and copies the second argument to the first i.e. it operates as a form of string assignment.
In C you CANNOT assign strings as:
filename = "prog.c" /* WRONG */
strcpy( filename, "prog.c"); /* CORRECT */
21

The function strcmp() is another string handling function. It takes two strings as arguments and
returns 0 if the two strings are the same. As for assignment, you cannot test string equality with ==
i.e.
if (filename == "prog.c") /* WRONG */
if (strcmp(filename,"prog.c")==0) /* CORRECT */
Note: The above program crashes if you run it as:
% count w
or
% count l
This is because in these cases we failed to test if there was a 3 rd argument containing the filename to
be processed. We simply try to access this non-existent argument and so cause a memory violation.
This gives rise to a so-called "bus error" in a Unix environment.
As an exercise, insert code to correct this failure.
Exercise: Write a copy command to operate like the Unix cp command that takes it files from the
command line:
% copy file newfile

--- Additional Exercises --You may like to attempt these exercises when you have finished the rest of this text, if you
find you have some spare time on your hands. You may wish to complete them when you get
home, if you have the facilities available to you:

Change the filename text to PRN: - this should tell Pascal to send the output not to a
file, but instead to the printer. Note that the success of this depends on how the printer
for your computer is set-up.
If you have the time, see if you can work out how to change the program to take a
filename from the keyboard, and store the text to that file instead of the fixed
constant.
Additionally, see if you can change the program to write different courses to different
files so the filename will have to be entered at the keyboard for each course.
Careful that you open and close the file for each course.

22

You might also like