CTutor chapter 10

                       Chapter 10 - File Input/Output


                              OUTPUT TO A FILE

             Load  and  display  the file named FORMOUT.C  for  your

        first example of writing data to a file.  We begin as before

        with the "include" statement for "stdio.h", then define some

        variables for use in the example including a rather  strange

        looking new type.

             The  type  "FILE"  is used for a file variable  and  is

        defined in the "stdio.h" file.   It is used to define a file

        pointer  for use in file operations.   The definition  of  C

        contains  the requirement for a pointer to a "FILE",  and as

        usual, the name can be any valid variable name.

                               OPENING A FILE

             Before we can write to a file,  we must open it.   What

        this  really means is that we must tell the system  that  we

        want  to  write to a file and what the filename is.   We  do

        this with the "fopen" function illustrated in the first line

        of the program.   The file pointer, "fp" in our case, points

        to   the  file  and  two  arguments  are  required  in   the

        parentheses,  the filename first, followed by the file type. 

        The filename is any valid DOS filename, and can be expressed

        in  upper  or lower case letters,  or even mixed if  you  so

        desire.   It is enclosed in double quotes.  For this example

        we have chosen the name TENLINES.TXT.   This file should not

        exist  on your disk at this time.   If you have a file  with

        this  name,  you should change its name or move  it  because

        when  we execute this program,  its contents will be erased. 

        If you don't have a file by this name,  that is good because

        we will create one and put some data into it.

                               READING ("r")

             The  second parameter is the file attribute and can  be

        any of three letters,  "r",  "w",  or "a", and must be lower

        case.   When an "r" is used, the file is opened for reading,

        a "w" is used to indicate a file to be used for writing, and

        an  "a" indicates that you desire to append additional  data

        to the data already in an existing file.  Opening a file for

        reading  requires that the file already exist.   If it  does

        not exist,  the file pointer will be set to NULL and can  be

        checked by the program.

                               WRITING ("w")

             When  a file is opened for writing,  it will be created

        if it does not already exist and it will be reset if it does

        resulting in deletion of any data already there.




                                   Page 66









                       Chapter 10 - File Input/Output


                              APPENDING ("a")

             When a file is opened for appending, it will be created

        if it does not already exist and it will be initially empty. 

        If  it does exist,  the data input point will be the end  of

        the  present data so that any new data will be added to  any

        data that already exists in the file.

                           OUTPUTTING TO THE FILE

             The  job of actually outputting to the file  is  nearly

        identical  to  the  outputting we have already done  to  the

        standard output device.   The only real differences are  the

        new  function names and the addition of the file pointer  as

        one  of  the function arguments.   In the  example  program,

        "fprintf" replaces our familiar "printf" function name,  and

        the  file  pointer  defined earlier is  the  first  argument

        within  the  parentheses.   The remainder of  the  statement

        looks  like,  and  in  fact is identical  to,  the  "printf"

        statement.

                               CLOSING A FILE

             To close a file,  you simply use the function  "fclose"

        with the file pointer in the parentheses.  Actually, in this

        simple  program,  it  is  not necessary to  close  the  file

        because   the  system  will  close  all  open  files  before

        returning to DOS.  It would be good programming practice for

        you to get in the habit of closing all files in spite of the

        fact  that they will be closed automatically,  because  that

        would act as a reminder to you of what files are open at the

        end of each program.

             You can open a file for writing,  close it,  and reopen

        it  for  reading,  then  close it,  and open  it  again  for

        appending,  etc.   Each time you open it,  you could use the

        same file pointer,  or you could use a different  one.   The

        file  pointer  is simply a tool that you use to point  to  a

        file and you decide what file it will point to.

             Compile  and run this program.   When you run  it,  you

        will  not  get any output to the monitor because it  doesn't

        generate any.   After running it, look at your directory for

        a file named TENLINES.TXT and "type" it.  That is where your

        output will be.   Compare the output with that specified  in

        the program.  It should agree.

             Do not erase the file named TENLINES.TXT yet.   We will

        use it in some of the other examples in this chapter.





                                   Page 67









                       Chapter 10 - File Input/Output


                  OUTPUTTING A SINGLE CHARACTER AT A TIME

             Load the next example file,  CHAROUT.C,  and display it

        on your monitor.  This program will illustrate how to output

        a single character at a time.

             The  program begins with the "include" statement,  then

        defines  some variables including a file pointer.   We  have

        called the file pointer "point" this time, but we could have

        used any other valid variable name.  We then define a string

        of characters to use in the output function using a "strcpy"

        function.   We are ready to open the file for appending  and

        we  do so in the "fopen" function,  except this time we  use

        the  lower cases for the filename.   This is done simply  to

        illustrate  that  DOS  doesn't care about the  case  of  the

        filename.  Notice that the file will be opened for appending

        so  we  will  add  to the lines  inserted  during  the  last

        program.

             The  program is actually two nested "for"  loops.   The

        outer  loop  is  simply a count to ten so that  we  will  go

        through the inner loop ten times.   The inner loop calls the

        function  "putc" repeatedly until a character in "others" is

        detected to be a zero.

                            THE "putc" FUNCTION

             The  part  of the program we are interested in  is  the

        "putc" function.   It outputs one character at a  time,  the

        character  being  the first argument in the parentheses  and

        the  file pointer being the second and last  argument.   Why

        the  designer of C made the pointer first in  the  "fprintf"

        function, and last in the "putc" function is a good question

        for which there may be no answer.   It seems like this would

        have been a good place to have used some consistency.

             When  the textline "others" is exhausted,  a newline is

        needed because a newline was not included in the  definition

        above.   A  single "putc" is then executed which outputs the

        "\n" character to return the carriage and do a linefeed.

             When  the outer loop has been executed ten  times,  the

        program  closes the file and terminates.   Compile  and  run

        this  program but once again there will be no output to  the

        monitor.

             Following  execution  of the program,  "type" the  file

        named  TENLINES.TXT and you will see that the 10  new  lines

        were  added to the end of the 10 that already  existed.   If

        you run it again,  yet another 10 lines will be added.  Once





                                   Page 68









                       Chapter 10 - File Input/Output


        again,  do  not  erase  this file because we are  still  not

        finished with it.

                               READING A FILE

             Load  the file named READCHAR.C and display it on  your

        monitor. This is our first program to read a file.

             This program begins with the familiar  "include",  some

        data  definitions,  and  the  file opening  statement  which

        should  require no explanation except for the fact  that  an

        "r"  is  used  here because we want to  read  it.   In  this

        program,  we  check to see that the file exists,  and if  it

        does,  we  execute  the  main body of the  program.   If  it

        doesn't,  we print a message and quit.  If the file does not

        exist,  the system will set the pointer equal to NULL  which

        we can test.

             The  main body of the program is one "do while" loop in

        which a single character is read from the file and output to

        the monitor until an EOF (end of file) is detected from  the

        input  file.   The  file is then closed and the  program  is

        terminated.

                         CAUTION  CAUTION  CAUTION

             At  this point,  we have the potential for one  of  the

        most  common and most perplexing problems of programming  in

        C.   The  variable  returned from the "getc" function  is  a

        character,  so  we  could  use a "char"  variable  for  this

        purpose.   There is a problem with that however,  because on

        some,  if not most,  implementations of C, the EOF returns a

        minus  one  which a "char" type variable is not  capable  of

        containing.  A "char" type variable can only have the values

        of  zero to 255,  so it will return a 255 for a minus one on

        those  compilers that use a minus one for EOF.   This  is  a

        very   frustrating  problem  to  try  to  find  because   no

        diagnostic is given.   The program simply can never find the

        EOF  and will therefore never terminate the loop.   This  is

        easy  to prevent,  always use an "int" type variable for use

        in returning an EOF.   You can tell what your compiler  uses

        for  EOF  by  looking  at the "stdio.h" file  where  EOF  is

        defined.  That is the standard place to define such values.

             There is another problem with this program but we  will

        worry  about it when we get to the next program and solve it

        with the one following that.

             After  you  compile  and  run  this  program  and   are

        satisfied  with the results,  it would be a good exercise to

        change the name of "TENLINES.TXT" and run the program  again



                                   Page 69









                       Chapter 10 - File Input/Output


        to see that the NULL test actually works as stated.  Be sure

        to  change  the name back because we are still not  finished

        with "TENLINES.TXT".

                          READING A WORD AT A TIME

             Load  and  display  the file named  READTEXT.C  for  an

        example of how to read a word at a time.

             This  program  is nearly identical as the  last  except

        that  this program uses the "fscanf" function to read  in  a

        string  at  a  time.   Because the "fscanf"  function  stops

        reading  when it finds a space or a  newline  character,  it

        will read a word at a time, and display the results one word

        to  a line.   You will see this when you compile and run it,

        but first we must examine a programming problem.

                             THIS IS A PROBLEM

             Inspection of the program will reveal that when we read

        data in and detect the EOF, we print out something before we

        check  for the EOF resulting in an extra line  of  printout. 

        What  we usually print out is the same thing printed on  the

        prior  pass  through  the loop because it is  still  in  the

        buffer "oneword".  We therefore must check for EOF before we

        execute  the  "printf"  function.   This has  been  done  in

        READGOOD.C,  which  you will shortly examine,  compile,  and

        execute.

             Compile  and execute the original program we have  been

        studying, READTEXT.C and observe the output.  If you haven't

        changed  TENLINES.TXT you will end up with "Additional"  and

        "lines."  on  two  separate lines  with  an  extra  "lines."

        displayed because of the "printf" before checking for EOF.

             Compile  and  execute READGOOD.C and observe  that  the

        extra  "lines." does not get displayed because of the  extra

        check for the EOF in the middle of the loop.   This was also

        the problem referred to when we looked at READCHAR.C,  but I

        chose  not  to expound on it there because the error in  the

        output was not so obvious.

                        FINALLY, WE READ A FULL LINE

             Load and display the file READLINE.C for an example  of

        reading  a complete line.   This program is very similar  to

        those we have been studying except for the addition of a new

        quantity, the NULL.

             We  are  using "fgets" which reads in an  entire  line,

        including  the newline character into a buffer.   The buffer



                                   Page 70









                       Chapter 10 - File Input/Output


        to be read into is the first argument in the function  call,

        and  the maximum number of characters to read is the  second

        argument,  followed by the file pointer.  This function will

        read  characters into the input buffer until it either finds

        a  newline  character,  or it reads the  maximum  number  of

        characters  allowed minus one.   It leaves one character for

        the end of string NULL character.   In addition, if it finds

        an  EOF,  it will return a value of NULL.   In our  example,

        when the EOF is found,  the pointer "c" will be assigned the

        value  of NULL.   NULL is defined as zero in your  "stdio.h"

        file.

             When  we find that "c" has been assigned the  value  of

        NULL,  we can stop processing data, but we must check before

        we print just like in the last program.

             Last of course, we close the file.

                       HOW TO USE A VARIABLE FILENAME

             Load  and display the file ANYFILE.C for an example  of

        reading  from any file.   This program asks the user for the

        filename desired,  reads in the filename and opens that file

        for reading.   The entire file is then read and displayed on

        the   monitor.    It  should  pose  no  problems   to   your

        understanding so no additional comments will be made.

             Compile  and  run  this program.   When it  requests  a

        filename,  enter  the  name and extension of any  text  file

        available, even one of the example C programs.
       
                              HOW DO WE PRINT?

             Load  the  last example file in this chapter,  the  one

        named  PRINTDAT.C  for an example of  how  to  print.   This

        program  should not present any surprises to you so we  will

        move very quickly through it.

             Once  again,  we  open TENLINES.TXT for reading and  we

        open PRN for writing.  Printing is identical to writing data

        to  a disk file except that we use a standard name  for  the

        filename.   There  are  no definite standards as far as  the

        name  or names to be used for the printer,  but some of  the

        usual names are,  "PRN",  "LPT",  "LPT1", and "LPT2".  Check

        your documentation for your particular implementation.

             Some  of  the newest compilers use  a  predefined  file

        pointer  such as "stdprn" for the print file.   Once  again,

        check your documentation.





                                   Page 71









                       Chapter 10 - File Input/Output


             The  program is simply a loop in which a  character  is

        read, and if it is not the EOF, it is displayed and printed. 

        When the EOF is found, the input file and the printer output

        files are both closed.

             You can now erase TENLINES.TXT from your disk.  We will

        not be using it in any of the later chapters.


        PROGRAMMING EXERCISES

        1.   Write a program  that will prompt for a filename for  a

             read file,  prompt for a filename for a write file, and

             open both plus a file to the printer. Enter a loop that

             will read a character,  and output it to the file,  the

             printer, and the monitor. Stop at EOF.

        2.   Prompt for a  filename to read. Read the file a line at

             a time and display it on the monitor with line numbers.


































                                   Page 72

Comments

Popular posts from this blog

BOTTOM LIVE script

Fawlty Towers script for "A Touch of Class"