4.10.1. Dependencies on low-level functions

The dependencies of the higher-level function on lower-level functions is shown in Table 4.14. If you define your own versions of the lower-level functions, you can use the library versions of the higher-level functions directly. fgetc() uses __FILE, but fputc() uses __FILE and ferror().

Table 4.14. Input/output dependencies

Low-level objectDescriptionfprintfprintffwritefputsputsfscanfscanffreadreadfgetsgets
__FILEThe file structurexxxxxxxxxxx
__stdinThe standard input object of type __FILE------x-x-x
__stdoutThe standard output object of type __FILE-x--x------
fputc()Outputs a character to a filexxxxx------
ferror()Returns the error status accumulated during file input/outputxxx--------
fgetc()Gets a character from a file-----xxxxxx
__backspace()Moves file pointer to previous character-----xx----

See the ANSI C Reference for syntax of the low-level functions.

printf family

The printf family consists of _printf(), printf(), _fprintf(), fprintf(), vprintf(), and vfprintf(). All these functions use __FILE opaquely and depend only on the functions fputc() and ferror(). The functions _printf() and _fprintf() are identical to printf() and fprintf() except that they cannot format floating-point values.

The standard output functions of the form _printf(...) are equivalent to:

fprintf(& __stdout, ...) 

where __stdout has type __FILE.

scanf family

The scanf() family consists of scanf() and fscanf(). These functions depend only on the functions fgetc(), __FILE, and __backspace().

The standard input form scanf(...) is equivalent to:

fscanf(& __stdin, ...)

where __stdin has type __FILE.

fwrite(), fputs, and puts

If you define your own version of __FILE, and your own fputc() and ferror() functions and the __stdout object, you can use all of the printf() family, fwrite(), fputs(), and puts() unchanged from the library. Example 4.19 shows how to do this. Consider modifying the system routines if you require real file handling.

Example 4.19. printf() and __FILE

#include <stdio.h>	
struct __FILE {	
    int handle;	
    /* Whatever you need here (if the only files you are using
       is the stdoutput using printf for debugging, no file
       handling is required) */	
};
FILE __stdout;	
int fputc(int ch, FILE *f)	
{
    /* Your implementation of fputc */	
    return ch;	
}
int ferror(FILE *f)	
{   
    /* Your implementation of ferror */	
    return EOF;	
}
void test(void)	
{
    printf("Hello world\n");  /* This works ... */	
}

By default, fread() and fwrite() call fast block input/output functions that are part of the ARM stream implementation. If you define your own __FILE structure instead of using the ARM stream implementation, fread() and fwrite() will call fgetc() instead of calling the block input/output functions. See also the implementation in \Examples\Embedded\embed\retarget.c.

fread(), fgets(), and gets()

The functions fread(), fgets(), and gets() are implemented as a loop over fgetc() and ferror(). Each uses the FILE argument opaquely.

If you provide your own implementation of __FILE, __stdin (for gets()), fgetc(), and ferror(), you can use these functions directly from the library.

Copyright © 1999-2001 ARM Limited. All rights reserved.ARM DUI 0067D
Non-Confidential