Tuesday, April 17, 2012

The Standard C Library for Linux, Part Three: formatted input/output

The last article was on character I/O in the standard input/output library <stdio.h>.  This article is on formatted input and output.   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 formatted input output we will read in a file containing a number and a label.  We will subtotal the items by label and print out the subtotal with its label along with a total for all subtotals.  The example is example3.c and the data file is example3.dat.

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 items 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.  See corrections at end of the document to review corrections to the previous articles.

Formatted Output
    #include <stdio.h>int   printf(const char *format, ...);
    int  fprintf(FILE *stream, const char *format, ...);
    int  sprintf(char *str, const char *format, ...);
    int snprintf(char *str, size_t size, const  char  *format, ...);
const char *format is a format that will be used to process the following arguments.
... is a variable number of arguments that must match the number of arguments used in const char *format.
FILE *stream is a previously fopened stream.
char *str is a string.
size_t size is the maximum size of string that will be produced, any excess is lost. printf is used to print out a formatted sequence of characters to standard out.
int x=5;
printf("We have %d apples.\n", x);
This example prints to stdout "We have 5 apples." with a newline following.

fprintf is used to print out a formatted sequence of characters to a file.
fprintf(stderr, "DEBUG\t%s\t%s\t%f",  dateString, messageString, errorNumber);
Could print to stderr, "DEBUG    199808291055    you are here    1234.4567" followed by a newline.

sprintf is used to print out a formatted sequence of characters to a character array.
float x=99.1234;
sprintf(string, "%d", x)
This would create a string that contained the characters '9', '9', '.', '1','2','3','4'.   This is the reverse to the atoi function that we will cover next month.

snprint is used to print out a formatted sequence of characters to a string.
 
float x=99.1234;
returnValue=sprintf(string, 4, "%d", x)
This will create a string with the characters '9','9','.','1', returnValue will contain a -1 because the field was truncated.
Formatted Input
    #include <stdio.h>int  scanf( const char *format, ...);
    int fscanf( FILE *stream, const char *format, ...);
    int sscanf( const char *str, const char *format, ...);
const char *format is a format that will be used to process the following arguments.
... is a variable number of arguments that must match the number of arguments used in const char *format.
FILE *stream is a previously fopened stream.
char *str is a string.
size_t size is the maximum size of string that will be produced, any excess is lost. These functions return an EOF on a read error, or the number of items that were converted, zero or more.
scanf will read in a format from standard input.
scanf("%f%2d%d", float1, int1, int2)
with the following on stdin:
12.34 4567
will set float1=12.34, int1=45 and int2=67.
fscanf will read in a format from the given stream.
fscanf(stdin,"%f%2d%d", float1, int1, int2)
This example is equivilent to the scanf example.
sscanf will read a format from the given string.
sscanf(string, "%f%2d%d", float1, int1, int2)
Will scan string for the float and decimal values.

Format Strings
The format will look like the above examples.  A more general desription is as follows:
A format string contains zero or more of the following conversion specifications:
%                  A conversion specification is introduced with this required character.
flags              followed by zero or more flags.
width            followed by an optional width field.
precision      followed by an optional precision field.
argument     followed by an optional argument that differs by specific conversions.
conversion   ending in a required conversion type.

Flags
    These are used to change the default behavior of the conversion.
-            left justify the field.
           used a sign with a number conversion.
#            use 0 in front of octal conversions, 0x in front of hex conversions and a decimal point with decimal conversions.
0            pad number conversions with leading zeros, ignore if a - is present.
space     if a space follows the % then a space will be placed before the output, ignore if a - is present.

Field Width
    The number of characters wide a field is.  Spaces are used to pad the extra characters if a value is not as wide as the given width.  If the value is larger than this number the field will expand to fit the number.

Precision
    The minimum number of digits to appear for integer types or the number of digits to apear after a floating point number or the maximum number of characters to print from a string.  This takes the form of a decimal point followed by an optional number.  If no number is given the precision defaults to 0.

Argument
    These will be discussed with each relevant conversion.  They are h, l, or L.

Conversions
      int to signed decimal        -9999 or 99
i        int to signed decimal        -9999 or 99
o       unsigned int to unsigned octal     8 becomes 10
u       unsigned int to decimal                 1 becomes 1
      unsigned int to hexidecimal       13 becomes 1d
     unsigned int to hexidecimal        13 becomes 1D
h is used in front of the above 6 to convert from the short int and unsigned short int to whatever.
l is used in front of the above 6 to convert from the long int and unsigned long int to whatever.
f        double to decimal        -9999.99 or 99.9
      double to scientific notation           -9.999e+99  or 9.9e-9
E      double to scientific notation            -9.999E+99 or 9.9E-9
g       double to decimal (f) or scientific (e) if the # of digits are equal to or greater than the precision.
G     double to decimal (f) or scientific (E) if the # of digits are equal to or greater then the precision.
L is used in front of the above 5 to convert from long double to whatever.
c       int to unsigned char      65 becomes an A in standard ASCII
s       pointer to string prints out the string
      pointer to an int into which the number of characters already written to stream will be placed.
h is used in front of the above 1 to specify a short int.
l is used in front of the above 1 to specify a long int.
%    a %% will write out a single %.  This is the way to print a % when needed.



A correction to Part Two:
    Date: Wed, 12 Aug 1998 11:27:08 +0200
    From: Lars Hesdorf <hesdorf@ibm.net>
    To: jrogers@u.washington.edu
    Subject: The Standard C Library for Linux, Part Two"Hej James M. Rogers
    You wrote somewhere in "The Standard C Library for Linux, Part Two"
    "putchar writes a character to standard out.  putchar(x) is the same as
    fputc(x, STDIN)"
    You probably meant "...fputc(x, STDOUT)".
    Lars Hesdorf
    HESDORF@IBM.NET
Yes I did, thanks a lot.  One more problem with all of those examples,  STDOUT and STDIN are suposed to be lower case; stdout and stdin.  Sorry if this caused anyone any frustrations.

Bibilography:

The ANSI C Programming Language, Second Edition, Brian W. Kernighan, Dennis M. Ritchie, Printice Hall Software Series, 1988 The Standard C Library, P. J. Plauger, Printice Hall P T R, 1992
The Standard C Library, Parts 1, 2, and 3, Chuck Allison, C/C++ Users Journal, January, February, March 1995
STDIO(3), BSD MANPAGE, Linux Programmer's Manual, 29 November 1993

No comments:

Post a Comment