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


know the files name.  If the function fails it returns a NULL pointer of type (FILE *)0.

    char  *tmpnam(char *string)

This function returns a filename in the tmp directory that is unique, or a NULL if there is an error.  Each additional call overrides the previous name so you must move the name somewhere else if you need to know the name after you open the file.

Stream Buffering
Normally a stream is block buffered, unless it is connected to a terminal like stdin or stdout.  In block buffered mode the stream reads ahead a set amount a and then gives you what the input that you ask for as you ask for it.  Sometimes you want this to be bigger or smaller to improve performance in some program.  The following four functions can be used to set the buffering type and the size of the buffers.  The defaults are normally pretty good so you shouldn't have to worry too much about these.
    int     setbuf( FILE *stream, char *buf);
    int  setbuffer( FILE *stream, char *buf, size_t size);
    int setlinebuf( FILE *stream);
    int    setvbuf( FILE *stream, char *buf, int mode , size_t size);


Where mode is one of the following:
    _IONBF unbuffered, output sent as soon as received.
    _IOLBF line buffered, output sent as soon as a newline is received.
    _IOFBF fully buffered, output isn't sent until size characters are received.

setbuf is an alias for     setvbuf(stream,  buf,  buf  ?  _IOFBF   :   _IONBF, BUFSIZ);
setbuffer is an alias for  setvbuf(stream,  buf,  buf  ?  _IOFBF   :   _IONBF, size);
setlinebuf is an alias for setvbuf(stream, (char *)NULL, _IOLBF, 0);

setvbuf sets a buffer for the given stream of size_t size and of buffer mode.

Stream Posistioning
Once you open a stream you are located at a certain postition depending on what mode you opened the stream in, as you read or write your position increases with each character.  You can see where you are at in the stream and jump to any position in the stream.  If you are writing a database program you don't want to have to read and ignore a million characters to get to the record that you want, you want to be able to jump right to the record and start reading.
Note that terminals cannot have their stream repositioned, only block devices (like hard drives) will allow this.

Also note that if you open a file for writing and use fseek to go out 10,000 bytes, write one character and then close the file that you will not have a file of 10,001 bytes.  The file will be much smaller.  This is called a sparse file.  If you move a sparse file using the mv command it will not change size because a mv is only a change to the directory structure, not the file.  If you cp or tar a sparse file then it will expand out to its true size.

    int   fseek( FILE *stream, long offset, int whence);
    long  ftell( FILE *stream);
    void rewind( FILE *stream);
    int fgetpos( FILE *stream, fpos_t *pos);
    int fsetpos( FILE *stream, fpos_t *pos);


FILE *stream is a pointer to an already existing stream.
long offset is added to the position indicated by the whence.
int whence is SEEK_SET, SEEK_CUR, or SEEK_END depending on where you want the offset to be applied to:  the beginning, the current position or the end.
fpos_t *pos is a complex file position indicator.  On some systems you must use this to get and set stream positions.
  
If these functions are successful fgetpos, fseek, fsetpos return  0,  and  ftell returns the current offset.  Otherwise, EOF is returned.  There is no return value from rewind.

fseek sets the file position in the stream to the value of offset plus the position indicated by the whence, either the begginning, the current or the end of file to get the new position in the stream.  This is useful for reading along, adding something to the end of the stream and then going back to reading the stream where you left off.

ftell returns the current position of the stream.

rewind sets the current position to the beginning of the stream.  Notice that no error code is returned.  This function is assumed to always suceed.

fgetpos is used like ftell to return the position of the stream.  The position is returned in the pos variable which is of type fpos_t.

fsetpos is used like fseek in that it will set the current postion of the stream to the value in pos.

On some systems you have to use fgetpos and fsetpos in order to reliably position your stream.

Error Codes
When any of the above functions return an error you can see what the error was and even get a text error message to display for the user.  There are a group of functions that deal with error values.  It is enough for now to be able to see that you have an errors and stop.
However, if you write a nice GUI word processor you don't want the program to stop everytime it can't open a file.  You want it to display the error message to the user and continue.  In a future article I will deal this error code functions, or someone else can summarize them for us and send in an article and some commented source code to show us how it's done.

If anyone is interested the functions are: clearerr, feof, ferror, and fileno.

Conclusion
Well that's enough for this month.  I have learned a lot and I hope you have as well.  Most of this information is available through man page system but the dates on these are 4 years old.  If anyone has updates on any of this information please send it to me and I will correct myself in further articles.
Next month I want to talk about input and output.  I will take the simple program above and add some functionallity to it to add a column of numbers and output the results to standard out.  Hopefully this example program can grow into something useful.


Part Two: <stdio.h> character input/output


The last article was on file operations in the standard input/output library <stdio.h>.  This article is on reading and writing characters, strings and arrays to and from a stream.   I am assuming a knowledge of c programming on the part of the reader.  There is no guarantee of accuracy in any of this information nor suitability for any purpose.

As an example of character based processing we will use a program that reads the number of characters, words and lines of a file from standard input and prints the results out to standard out.  Any errors encountered will be printed to standard error.  This will be a weak version of  wc.  (type `man wc` for more information on this UNIX utility program.

The code examples given for each function will typically not run unless the the <angle bracked> items are replaced with real code.  Normally these are things that have to be treated differently depending on what you are trying to do.  As always, if you see an error in my documentation please tell me and I will correct myself in a later document.

  
#include <stdio.h>     /* include the proper headers */

#define  IN 1          /* looking inside a word */
#define OUT 0          /* looking at white space */

/* count the number of lines, words and characters in standard input */

main() {

    int c,             /* holds the character returned by getchar */
        characters,    /* the number of characters */
        lines,         /* the number of lines */
        words,         /* the number of words */
        state;  


Page : << Previous 3  Next >>