Topic : Standart C Library for Unix
Author : James Rogers
Page : 1 Next >>
Go to page :


The Standard C Library for Linux,
By James M. Rogers


Part one: <stdio.h> file functions

C is a very small language.  This is a good thing.  C programmers will use nearly the entire C language every time they write a fair sized program.  The standard C library extends the functionality of C in a way that is predictable on multiple systems.  The library gives us tools like scanf() and printf() that make reading and writing formatted output much easier than working with blocks of characters using read() and write().  Also when you move from one C programming environment to another, the functionality of printf() will be the same.  You don't have to relearn how to print formatted output every time you change machines.

In this series of articles I will discuss the tools that are available for the programmers in the standard C library.  At the end is a bibliography of the books and articles that I used to get this information.  I refer to these books and magazines on a daily basis when I program.  If you want to work as a C programmer I strongly recommend that you buy and read these books and magazines.

Many times the standard functions are overlooked and reinvented by programmers (including myself!) to do things like seeing if a character is a letter by:

            (c=>'a' || c<='z' && c=>'A' || c<='Z')

instead of using

            isalpha(c);

The second form is much easier to read and figure out.  There is another reason to use the second form.  The first example only works for ASCII character sets, the second will work on _any_ machine.  If you want to write portable code (code that can be compiled and ran on any machine with very minor changes) then use the standard C library.

Several times in the past I have written code that took time to write and debug and interface to the rest of my program only to discover that there was already a function that did what I wanted to do.  A few months ago I was writing my own Multi User Dimension (MUD), based on a client/server article in Linux Journal, and I needed to process what the user had entered, one word at a time.  So I wrote my own string tokenizer.  Turns out I could have used the strtok() function to do almost the exact same thing.  And other people will know what the strtok() function does without having to decipher my code.

Make your life easier, use the standard C library.  It will also help all of us who try to update and maintain your code later.

The GNU compiler, gcc, comes with the GNU standard C library.  This compiler is one of the best in the world and the GNU standard C library conforms almost exactly to the standard.  In the places where the standard is imprecise, you can expect very reasonable behavior from both the compiler and the library.  I am going to discuss the GNU standard C library in these articles.

The <stdio.h> library handles the standard input and output functions for C programmers.  It is also by far the largest library.  Because the library is so large I am going to group the commands in these sections:  file operations, input and output.

Now before we talk about files we need to agree on the words that we are going to use.  In Linux a file or device is considered to be a stream of data.  This stream of data that is associated with a file or hardware device is accessed by your program opening the file or device.  Once the stream is opened then you can read and/or write to it.

Three streams are opened automatically when you execute a program.  Standard input (stdin), standard output (stdout), and standard error (stderr).  These can all be redirected by your shell when you run the program but normally stdin is your keyboard and stdout and stderr both go to your monitor.

After you are done with your streams you need to tell the operating system to clean up buffers and finish saving data to the devices.  You do this by closing the stream.  If you don't close your stream then it is possible to lose data.  stdin, stdout and stderr are all closed automatically the same way they are opened automatically.

One of the most important things to remember when dealing with devices and files is that you are dealing with the real world.  Don't assume that the function is going to work.  Evan something like printf can fail. Disks fill up or occasionally fail, users input the wrong data, processors get too busy, other programs have your files locked.  Murphy's Law is in full effect when it comes to computer systems. Every function that deals with the real world returns an error condition if the function failed.  Always check every return value and take the appropriate action when there is an error condition.  Exceptions are not errors unless they are handled badly. Exceptions are opportunities for extra computation (William Kahan, on exception handling.)

The first example is to basically show how to open a file for reading.  It just dumps a file called test in the current directory to the standard out.  All exceptions are reported to standard error and then program halted is with an error return.  It should produce an error if a file called test doesn't exist.


#include <stdio.h>    /* this is a compiler directive that tells the
                         the compiler that you are going to be using
                         functions that are in the standard input /
                         output library
                      */
main (){

/* declare variables */
    FILE *stream;            /* need a pointer to FILE for the stream */
    int buffer_character;    /* need an int to hold a single character */

/* open the file called test for reading in the current directory */
    stream = fopen("test", "r");

/* if the file wasn't opened correctly than the stream will be
    equal to NULL.  It is now customary to represent NULL by casting
    the value of 0 to the correct type yourself rather than having the
    compiler guess at the type of NULL to use.
*/
    if (stream == (FILE *)0) {
        fprintf(stderr, "Error opening file (printed to standard error)\n");
        exit (1);
        }  /* end if */

/* read and write the file one character at a time until you reach
    end-of-file on either our file or output.  If the EOF is on file_descriptor
    then drop out of the while loop. if the end-of-file is on report write
    errors to standard out and exit the program with an error condition
*/
    while ((buffer_character=getc(stream))!=EOF) {
        /* write the character to standard out and check for errors */
        if((putc(buffer_character, stdout)) == EOF) {
            fprintf(stderr,"Error writing to standard out.  (printed to standard error)\n");
            fclose(stream);
            exit(1);
            }  /* end if */
        }  /* end while */

/* close the file after you are done with it, if file doesn't close then report and exit */
    if ((fclose(stream)) == EOF) {
  


Page : 1 Next >>