Skip to main content

stdio.h

stdio.h is the C language standard I/O library for reading and writing to files, and also for console input and output.

Standard I/O Functions

The following functions are used for console input and output.

  • printf(): output to the console, see the chapter on Basic Syntax for details.
  • scanf(): reads input from the console, see the chapter on I/O Functions for details.
  • getchar(): reads a character from the console, see the chapter I/O Functions for details.
  • putchar(): writes a character to the console, see the chapter I/O Functions for details.
  • gets(): reads an entire line of input from the console (deprecated), see the chapter I/O Functions for details.
  • puts(): writes a string to the console, see the chapter I/O Functions for details.

File manipulation functions

The following functions are used for file manipulation, see the chapter on File Manipulation for details.

  • fopen(): opens a file.
  • fclose(): closes a file.
  • freopen(): opens a new file, associating a pointer to an already open file.
  • fprintf(): output to a file.
  • fscanf(): reads data from a file.
  • getc(): reads a character from a file.
  • fgetc(): reads a character from a file.
  • putc(): writes a character to the file.
  • fputc(): writes a character to the file.
  • fgets(): reads an entire line from a file.
  • fputs(): writes a string to the file.
  • fread(): reads binary data from a file.
  • fwrite(): writes binary data to the file.
  • fseek(): moves the file internal pointer to the specified location.
  • ftell(): get the current position of the file's internal pointer.
  • rewind(): resets the file internal pointer to the start of the file.
  • fgetpos(): gets the current position of the internal pointer to the file.
  • fsetpos(): sets the current position of the internal pointer to the file.
  • feof(): determine if the internal pointer points to the end of the file.
  • ferror(): return the status of the file error indicator.
  • clearerr(): resets the file error indicator.
  • remove(): removes a file.
  • rename(): rename a file, and move a file.

String manipulation functions

The following functions are used to manipulate strings, see the chapter on String Manipulation for details.

  • sscanf(): reads data from a string, see the chapter on I/O Functions for details.
  • sprintf(): output to a string.
  • snprintf(): output to a safer version of string, specifying the number of strings to output.

tmpfile()

The tmpfile() function creates a temporary file which exists only for the duration of the program, unless it is closed manually. It has the following prototype.

FILE* tmpfile(void);

`tmpfile() returns a pointer to a file that can be used to access the temporary file created by this function. If creation fails, a null pointer NULL is returned.

FILE* tempptr;
tempptr = tmpfile();

After calling the close() method to close the temporary file, the file will be automatically deleted.

tmpfile() has two drawbacks. One is that the file name of the temporary file cannot be known, and the other is that it is not possible to make the file permanent.

tmpnam()

The tmpname() function generates a name for the temporary file, ensuring that it will not be renamed with another file. It has the following prototype.

char* tmpname(char* s);

Its argument is a string variable into which tmpnam() copies the file name of the temporary file and returns a pointer to the string variable. If the generation of the filename fails, tmpnam() returns the null pointer NULL.

char filename[L_tmpname];

if (tmpnam(filename) ! = NULL)
// Output a filename such as /tmp/filew9PMuZ
printf("%s\n", filename);
else
printf("Something wrong!\n");

In the example above, L_tmpname is a macro defined by stdio.h that specifies the length of the file name of the temporary file.

The argument to tmpname() can also be a null pointer NULL, again returning a pointer to the filename string.

char* filename;
filename = tmpnam(NULL);

In the example above, the variable filename is the filename generated by tmpnam().

This function simply generates a filename which can later be opened and used with fopen().

fflush()

fflush() is used to empty the buffer. It accepts a file pointer as an argument and writes the contents of the buffer to that file.

``c fflush(fp);


If you do not need to save the contents of the buffer, you can pass the null pointer NULL.

```c
fflush(NULL);

`fflush() returns 0 if the flush was successful, otherwise it returns EOF.

Note that fflush() is generally only used to clear the output buffer (e.g. to write a file). If it is used to empty the input buffer (e.g. to read a file), it is undefined behaviour.

One use of fflush() is to force the output buffer without waiting for the enter key. Most systems are line cached, which means that the contents of the buffer are only output when a carriage return key is encountered (or the buffer is full, or the file is read to the end), and fflush() can output immediately without waiting for a carriage return key.

for (int i = 9; i >= 0; i--) {
printf("\r%d", i);
fflush(stdout);
sleep(1);
}

The above example is a countdown effect. \r is the enter key, which means that each round of the loop will return to the beginning of the current line, which is equivalent to deleting the output of the previous round of the loop. fflush(stdout) means immediate cached output to the display, this line is required, otherwise as the output of the previous line does not have a carriage return key, it will not trigger cached output and nothing will be displayed on the screen, it will just wait until the end of the program run before outputting it all at once.

setvbuf()

The setvbuf() function is used to define how a particular byte stream should be cached. It can take four arguments.

int setvbuf(FILE* stream, char* buffer, int mode, size_t size)

The first argument, stream, is the file stream.

The second parameter buffer is the address of the buffer.

The third argument, mode, specifies the mode of behaviour of the cache, which is one of the following three macros, all of which are defined in stdio.h.

  • _IOFBF: full cache. Read data from the stream only when the cache is empty; write data to the stream only when the cache is full. Normally, this is the default setting.
  • _IOLBF: line cache. Reads data from the stream one line at a time, or writes data to the stream one line at a time, i.e. reads and writes the cache in rows.
  • _IONBF: no cache. No cache is used, the device is read and written directly.

The fourth parameter, size, specifies the size of the buffer. A larger buffer provides better performance, while a smaller buffer saves space. stdio.h provides a macro BUFSIZ that indicates the system default buffer size.

It is meant to enable users to define their own file buffers before opening a file, rather than having to use the default buffer set when opening a file with the fopen() function.

char buffer[N];

setvbuf(stream, buffer, _IOFBF, N);

The above example sets the buffer for the file stream stream to start at address buffer, size N and mode _IOFBF.

The second argument to setvbuf() can be the null pointer NULL, in which case setvbuf() will create a buffer itself.

Note that the call to setvbuf() must be made before any operation is performed on the file stream.

If the call is successful, setvbuf() returns 0, otherwise it returns a non-zero value.

The following example adjusts the buffer to a line cache.

FILE *fp;
char lineBuf[1024];

fp = fopen("somefile.txt", "r");
setvbuf(fp, lineBuf, _IOLBF, 1024);

setbuf()

setbuf()` is an earlier version of setvbuf()`, which can be seen as a simplified version of the latter, and is also used to define the buffer for a particular byte stream.

void setbuf(FILE* stream, char* buffer);

Its first argument, stream, is the file stream, and its second argument, buffer, is the address of the buffer.

It can always be rewritten as setvbuf().

char buffer[BUFSIZ];

setbuf(stream, buffer);

// Equivalent to
setvbuf(stream, buffer, _IOFBF, BUFSIZ);

In the above example, BUFSIZ is a macro defined by stdio.h, indicating the system default buffer size.

The setbuf() function has no return value.

The second argument to setbuf(), if set to NULL, indicates that no caching is done.

setbuf(stdout, NULL);

// Equivalent to
setvbuf(stdout, NULL, _IONBF, 0);

ungetc()

ungetc() takes the last character read from inside the cache and puts it back into the cache, and the next operation to read the cache will start with that character. Some operations need to know what the next character is before deciding what should be done with it, and this function is useful in that case.

It has the following prototype.

int ungetc(int c, FILE *stream);

Its first argument is a character variable and its second argument is an open file stream. Its return value is the character that was put back into the cache, and on failure of the operation, it returns EOF.

int ch = fgetc(fp);

if (isdigit(ch)) {
ch = fgetc(fp);
}

ungetc(ch, fp);

In the above example, if the character read is not a digit, it is put back into the cache.

perror()

`perror() is used to add a custom string before the error message from stderr.

``c void perror(const char *s);


The argument to this function is the string to be added before the error message. It has no return value.

```c
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <errno.h>

int main(void) {
int x = -1;

errno = 0;
float y = sqrt(x);
if (errno ! = 0) {
perror("sqrt error");
exit(EXIT_FAILURE);
}
}

In the above example, finding the square root of -1 results in an error. The header file errno.h provides the macro errno which is set to a non-zero value whenever an error occurs in the previous operation. perror() is used to prefix the error message with a custom string of sqrt error.

Executing the above program will give you the following error message.

$ gcc test.c -lm
$ . /a.out
sqrt error: Numerical argument out of domain

Variable parameter manipulation functions

(1) Output functions

The following is a variant of the printf() function for outputting the variable argument list (va_list) of a function in the given format.

  • vprintf(): according to the given format, output to the console, the default is the monitor.
  • vfprintf(): outputs to a file in the given format.
  • vsprintf(): output to a string in the given format.
  • vsnprintf(): Outputs to a safe version of a string, in the given format.

They have the following prototypes, which are basically the same as the corresponding printf() family of functions, except that the last argument is a variable-argument object.

#include <stdio.h>
#include <stdarg.h>

int vprintf(
const char * restrict format,
va_list arg
);

int vfprintf(
FILE * restrict stream,
const char * restrict format,
va_list arg
);

int vsprintf(
char * restrict s,
const char * restrict format,
va_list arg
);

int vsnprintf(
char * restrict s,
size_t n,
const char * restrict format,
va_list arg
);

They both return the number of characters output, or a negative value if there is an error.

The first argument to vsprintf() and vsnprintf() can be NULL and is used to see how many characters will be written.

Here is an example.

int logger(char *format, ...) {
va_list va;
va_start(va, format);
int result = vprintf(format, va);
va_end(va);

printf("\n");

return result;
}

// output x = 12 and y = 3.20
logger("x = %d and y = %.2f", x, y);

(2) Input functions

The following variant of scanf() is used to input a variable list of parameters (va_list) in the given format.

  • vscanf(): reads from the console (default is keyboard) in the given format.
  • vfscanf(): reads from a file in the given format.
  • vsscanf(): reads from a string in the given format.

Their prototypes are as follows, and are essentially the same as the corresponding scanf() functions, except that the last argument is a variable argument object.

#include <stdio.h>
#include <stdarg.h>

int vscanf(
const char * restrict format,
va_list arg
);

int vfscanf(
FILE * restrict stream,
const char * restrict format,
va_list arg
);

int vsscanf(
const char * restrict s,
const char * restrict format,
va_list arg
);

They return the number of items successfully read, or EOF if an end-of-file or error is encountered.

Here is an example.

int error_check_scanf(int expected_count, char *format, ...) {
va_list va;

va_start(va, format);
int count = vscanf(format, va);
va_end(va);

assert(count == expected_count);

return count;
}

error_check_scanf(3, "%d, %d/%f", &a, &b, &c);