************* BACK AND FORTH PAGING SUBROUTINE ************

PAGEFLOP

If they want to quit, do so
 If They want to quit subsession, Do SO!
  Decrement LOCAL and GLOBAL Page Counters

FORWARD

  Increment LOCAL and GLOBAL Page Counters
   *************** END PAGEFLOP *********************
  ****** CHAPTER INTERNAL SELECTOR ALGORITHM ******

SELECTOR

   Reset Local Page Counter

SELAGAIN

 CHECK IF ONLY A <CR>

WRONGSEL

YOUR SELECTION IS NOT IN THE 0 - #SELIMIT  RANGE  Please try again

SELRTRN

    <<<<<< REVIEW CLEANING SUBROUTINE >>>>>>

AANVANG

Copyright CourseWare Technologies Inc., 1985-88


Lesson - 8


 TEXT FILES IN C 

P1

Text Files in C|Topics to Learn|8-0|11,41
  #              Topic
 ---            -------
  1   -   About the File Concept
  2   -   Text File Concepts
  3   -   Single Character Standard I/O
  4   -   Text File Operations
  5   -   Single Character File I/O
  6   -   Object Sizes, Dynamic Objects
  7   -   Formatted Text File I/O
  8   -   Lesson Review
  0   -   Return to the Main Menu

P2

Text Files in C|About the File Concept|8-1.1|13,53
     Any stream of information which is held on some 
external storage medium for input to, or output by
a computer is called a file.


     In C, you can manipulate files, that is, you can

                   *  create files, 
                   *  delete files, 
                   *  open files, 
                   *  close files,
                   *  read files, and 
                   *  write files.

P3

Text Files in C|Text File Concepts|8-2.1|9,50
     The UNIX operating system sees all files as 
having the same format.  It is the individual 
program that decides how to treat the information 
in the file(s).


     If a program treats the data in a file as 
characters (char) then we refer to that file as 
a text file.

P4

Text Files in C|Single Character Standard I/O|8-3.1|15,53
The function getchar() reads a single character from
the standard input, stdin.

The function putchar() writes a single character to
the standard output, stdout.


Following is an example using the functions getchar() and 
putchar().  Shown is another method for converting 
characters from lowercase to uppercase.  Employed 
are the macros islower() and toupper() which normally 
are defined in the include file /usr/include/ctype.h.  
The macro islower() returns TRUE if the argument is 
in the range of 'a' - 'z'.  The macro toupper() will 
convert the argument to uppercase.

P5

Text Files in C|Single Character Standard I/O|8-3.2|12,49
#include <stdio.h>
#include <ctype.h>   /* Type conversion macros */
main()
{
    int c;

    while ((c = getchar()) != EOF)
        if (islower(c))
            putchar(toupper(c));
        else
            putchar(c);
}

P6

Text Files in C|Text File Operations|8-4.1|18,56
     Prior to being able to use a text file you 
must open it using function fopen().

Syntax:      fp = fopen(file_name,  mode);

where fp is a file pointer, thus both fp and fopen() 
must be declared as:

FILE *fp, *fopen();


     fopen() returns a pointer to a file.

file_name holds file name, which may be a character 
string, a constant, or a variable.  

mode specifies how one intends to use the file; it 
is also a character string.

P7

Text Files in C|Text File Operations|8-4.2|18,54
     The allowable modes are:

         read         - specified as  "r"
         write        - specified as  "w"
         append       - specified as  "a"


     Note that opening a file with mode "w" will

   *  create a new file or rewrite the old one and
   *  return NULL if there is an error on file opening.


     The complement to function fopen() is a function
called fclose(fp) which will close a file whose file 
pointer is fp:

Syntax:                 fclose(fp);

P8

Text Files in C|Text File Operations|8-4.3|10,54
     fclose() will return 0 on success and EOF if any
errors were detected.


The following example illustrates the C library functions 
fopen() and fclose().  The fopen() is seen constantly in 
C programs; therefore, it is important to understand its 
structure.  The fopen() is called and the value it 
returns is assigned to fp.  If the value is not NULL, 
then the fopen() call was successful.

P9

Text Files in C|Text File Operations|8-4.4|13,47
#include <stdio.h>
main()
{
    char *file_name = "data_file";
    FILE *fp, *fopen();

    if ((fp = fopen(file_name, "r")) == NULL)
        printf("Error on file %s\n", file_name);
    else {
           :
        fclose(fp);
    }
}

P10

Text Files in C|Text File Operations|8-4.5|16,47
     The simplest C function for obtaining the next 
character from a text file is getc().  The inverse 
function for placing a character into a file is putc(), 
used as:

putc(c, fp);

Since stdin and stdout are text files we may use:

        c = getc(stdin) <==> c = getchar(); and
        putc(c,stdout)  <==> putchar();

putchar() and getchar() are defined as:

        #define getchar()      getc(stdin)
        #define putchar(c)     putc(c, stdout)

P11

Text Files in C|Single Character File I/O|8-5.1|15,54
The following example demonstrates one method of copying 
a text file.  The variables file_in and file_out hold 
the input and the output file names.  The C library 
function gets() reads a line of text from the standard 
input, replaces '\n' with '\0' and stores the result 
into its argument.  The statement that does all the 
work is:

       while (( c = getc(fp_in)) != EOF)
           putc(c, fp_out);

This copies one character at a time from the source file 
into the destination file.  The process terminator is the 
EOF character.  Note the position of the two fclose calls; 
fclose() is called only if the file was successfully opened.

SOL1

Text Files in C|Single Character File I/O|8-5.2|17,49
#include <stdio.h>
main()                /* copy file1 into file2 */
{
    char file_in[25],            /* file names */
         file_out[25];

    int c;
    char *gets();  /* reads a string from file */
    FILE *fp_in, *fp_out, *fopen();

/* EXECUTABLE CODE */

/* Prompt User For Input */
    printf("Enter input file_name\n");
    gets(file_in);
    printf("Enter output file_name\n");
    gets(file_out);

P13

Text Files in C|Single Character File I/O|8-5.3|14,53
/*  open input file for read, and output file for write */

    if ((fp_in = fopen(file_in, "r")) != NULL)
        if ((fp_out = fopen(file_out, "w")) != NULL){

            /*           COPY FILE        */
            while ((c = getc(fp_in)) != EOF)
                putc(c, fp_out);

            fclose(fp_out);
        }
        fclose(fp_in);
     }

P14

Text Files in C|Object Sizes, Dynamic Objects|8-6.1|10,54
     There are situations in which the object or even 
the size of the object is unknown prior to execution.  
However, there are functions which can help you in 
obtaining object size information:

strlen(string) returns the number of characters in
the string (not including '\0')

sizeof(var) is a compile time function that
returns the size of the object var in bytes.

P15

Text Files in C|Object Sizes, Dynamic Objects|8-6.2|13,54
FUNCTIONS:

             char *malloc(size)
                   unsigned size;

Creates, dynamically, an area in memory of length size 
bytes, and returns a pointer to it.

             free(ptr)
                 char *ptr;

Frees the area originally allocated by malloc() to which 
ptr is pointing.

P16

Text Files in C|Object Sizes, Dynamic Objects|8-6.3|12,59
The following program reads up to 100 text lines from the 
standard input and sorts lines alphabetically in ascending 
order.  It uses the function gets() to read a character 
string and uses the "shell-sort" method to sort lines.  The 
function read_lines() will read the lines and assign a 
pointer from the array line_ptr to every line.  This 
function will also return the number of lines read.  The 
function sort_lines() will sort the lines by replacing 
pointers rather than entire lines.  The function read_lines()
is the important one.  Once the area for the new line 
exists, the line may be copied into it and the buffer
line re-used for reading the next line.

P17

Text Files in C|Object Sizes, Dynamic Objects|8-6.4|17,51
#include <stdio.h>
#define  ERROR    -1
#define  LINES   100     /*  max number of lines */

main()                       /* sort input lines */
{
    char *line_ptr[LINES];     /* LINES pointers */
    int nlines;           /* line number counter */

    if ((nlines = read_lines(line_ptr,LINES)) >= 0)
    {
        sort_lines(line_ptr, nlines);
        write_lines(line_ptr, nlines);
    }
    else
        printf("ERROR on line input!\n");
}

P18

Text Files in C|Object Sizes, Dynamic Objects|8-6.5|15,54
#define   MAXLEN    750      /* maximum line length */
read_lines(lineptr, maxlines)   /* read input lines */
    char *lineptr[];        /* pointers to new lines */
    int maxlines;
{
    int len;
    unsigned nlines;             /* always positive */
    char *malloc(), line[MAXLEN], *gets(), *strcpy();

    nlines = 0;
    printf("Enter new line\n"); return(ERROR);
    while ((len = strlen(gets(line))) > 0) {
     if (nlines >= maxlines)  /*NO MORE BUFFER SPACE*/
          return(ERROR);

P19

Text Files in C|Object Sizes, Dynamic Objects|8-6.6|13,55
   else               /*  ALLOCATE SPACE FOR NEW LINE */

      if ((lineptr[nlines] = malloc((unsigned)line+1)
                           == NULL)
                /*  UNABLE TO ALLOCATE, RETURN ERROR! */
         return(ERROR);
      else         /*  COPY DATA INTO ALLOCATED SPACE */
         strcpy(lineptr[nlines++], line);
                               /* PROMPT FOR NEW LINE */
         printf("Enter new line\n");
  }
  return (nlines);          /* return number of lines */
}

P20

Text Files in C|Object Sizes, Dynamic Objects|8-6.7|10,49
write_lines(lineptr, nlines)  /* write output lines */
    char *lineptr[];
    int nlines;
{
    int i;

    printf("\nABOUT TO VERIFY LINES\n\n");
    for (i=0; i < nlines; i++)
        printf("%s\n", lineptr[i]);
}

P21

Text Files in C|Object Sizes, Dynamic Objects|8-6.8|18,51
sort_lines(v,n)  /* sort strings v[0] ... v[n-1] */
                        /* use shell sort method */
    char *v[], int n;
{
    int gap, i, j;  char *temp;
    printf("\n");                 /* skip a line */
    for (gap = n/2; i<n; i++)
       for (j = i-gap; j >= 0; j -= gap) {
          printf("Compare with j = %d, i = %d,
               gap = %d\n", j, i, gap);
          if ((strcmp (v[j], v[j+gap]) <= 0)
               break;
          if (strcmp (v[j], v[j+gap]) <= 0)
               break;
          temp = v[j];         /* do replacement */
          v[j] = v[j+gap];
          v[j+gap] = temp;    }
}

P22

Text Files in C|Object Sizes, Dynamic Objects|8-6.9|16,34
Picture of the program's action
-------------------------------

Enter new line
bbbbbbbbbbbbbbbbbbbbbbbbbbbbb
Enter new line
ddddddddddddddddddddddddddddddd
Enter new line
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
Enter new line
cccccccccccccccccccccccccccccccccc
Enter new line
99999999999999999999999999999
Enter new line
0000000000000000000000000000000
Enter new line
<CONTROL-d>

P23

Text Files in C|Object Sizes, Dynamic Objects|8-6.10|10,34
Picture of the program's action
-------------------------------

About to verify lines

0000000000000000000000000000000
99999999999999999999999999999
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
bbbbbbbbbbbbbbbbbbbbbbbbbbbbb
cccccccccccccccccccccccccccccccccc
ddddddddddddddddddddddddddddddd

P24

Text Files in C|Formatted Text File I/O|8-7.1|8,54
     The two complementary functions in C for formatted 
standard I/O are printf() and scanf().

The function scanf() is the input analog of printf() 
and provides many of the same conversion facilities.

Syntax:          scanf(control, arg1, arg2, ...);

P25

Text Files in C|Formatted Text File I/O|8-7.2|12,54
     After a successful read, scanf() will return the
number of successfully matched and assigned input items.  
It will return 0 on an error and EOF if the end of the 
file was encountered.


     In the format specifier string, type specifiers
are almost the same as that for printf().


      %  precedes variable type specifier.   *  means that
data for the following conversion specifier is to be skipped.

P26

Text Files in C|Formatted Text File I/O|8-7.3|15,54
     Input format specifiers for the function scanf()
include:

           %d - decimal integer
           %o - octal integer
           %x - hexadecimal integer
           %h - short integer
           %c - (single) character
           %s - character string
           %f - floating point number


     NOTE: Whenever scanf() is used, the arguments 
must be pointers to the data type specified in the 
control string.

P27

Text Files in C|Formatted Text File I/O|8-7.4|13,54
The following example demonstrates the library function 
for formatted input, scanf().  The function will try to
match the first three columns of the input with "%3d" 
(364), then it will look for a floating point number,
find 39, and convert it to 39.0.  Then it will look for 
an integer and find -1247.  Next, the function will
look for a character string of length 4 (834M).  If the 
blanks are not to be skipped, you should use the format 
specifier "%nc" where "n" is the number of fields to
read.  Note that the addresses rather than the values 
were sent as arguments to the function scanf().  This 
is a must since we want to see the updated values of 
the variables; scanf() will not run otherwise.

P28

Text Files in C|Formatted Text File I/O|8-7.5|14,40
int n;
float x;
char string[25];
    :
    :
scanf("%3d %f %*d %4s", &n, &x, string);

With the input:

36439      -1247       834m47

the following assignments take place:

n = 364, x = 39.0, string = "834m"

P29

Text Files in C|Formatted Text File I/O|8-7.6|8,58
The next program calculates the maximum and the minimum 
values.  The input comes from the standard input.  Once 
again, pay attention to the fact that the argument to 
scanf() is a pointer/address.  In the algorithm itself,
the max and the min values are initially set to 0.  If
the newly read value exceeds the maximum or is smaller 
than the minimum, then max and min are updated respectively.
Finally, the results are printed.

P30

Text Files in C|Formatted Text File I/O|8-7.7|17,51
#include <stdio.h>
main()  /* determine the maximum and the
   minimum integers in the input stream */
{
    float min = 0.0, max = 0.0,
          cur_input = 0.0;

    /*  READ INPUT UNTIL EOF          */

    while(scanf("%f", &cur_input) > 0) {
        if (cur_input > max)
            max = cur_input;
        else if (cur_input < min)
            min = cur_input;
    }
    printf("\n\nThe max = %f, the min = %f\n", max, min);
 }