I l@ve RuBoard Previous Section Next Section

16.9 C-Style I/O Routines

C++ allows you to use the C I/O library in C++ programs. Many times this occurs because someone took a C program, translated it to C++, and didn't want to bother translating the I/O calls. In some cases, the old C library is better and easier to use than the new C++ library. For example, C string-conversion routines such as std::sscanf and std::sprintf use a far more compact formatting specification system than their C++ counterparts. (Note that it is a matter of taste whether or not compact is better.)

The declarations for the structures and functions used by the C I/O functions are stored in the standard include file <cstdio>.

The declaration for a file variable is:

std::FILE *file_variable;      /* Comment */ 

For example:

#include <cstdio> 

std::FILE *in_file;  /* File containing the input data */ 

Before a file can be used, it must be opened using the function std::fopen. std::fopen returns a pointer to the file structure for the file. The format for std::fopen is:

file_variable = std::fopen(name, mode); 
file_variable

A file variable.

name

Actual name of the file ("data.txt", "temp.dat", etc.).

mode

Indicates whether the file is to be read or written. Mode is "w" for writing and "r" for reading.

The function std::fclose closes the file. The format of std::fclose is:

status = std::fclose(file_variable); 

The variable status will be zero if the std::fclose was successful or nonzero for an error.

C provides three preopened files. These are listed in Table 16-8.

Table 16-8. Standard files

File

Description

stdin

Standard input (open for reading). Equivalent to C++'s cin.

stdout

Standard output (open for writing). Equivalent to C++'s cout.

stderr

Standard error (open for writing). Equivalent to C++'s cerr.

 

(There is no C file equivalent to C++'s clog.)

The function std::fgetc reads a single character from a file. If there is no more data in the file, the function returns the constant EOF (EOF is defined in cstdio). Note that std::fgetc returns an integer, not a character. This is necessary because the EOF flag must be a noncharacter value.

Example 16-6 counts the number of characters in the file input.txt.

Example 16-6. copy/copy.cpp
#include <cstdio>
#include <cstdlib>      /* ANSI Standard C file */
#include <iostream>

const char FILE_NAME[] = "input.txt";   // Name of the input file

int main(  )
{
    int  count = 0;  // number of characters seen 
    std::FILE *in_file;   // input file 

    int ch;          // character or EOF flag from input 

    in_file = std::fopen(FILE_NAME, "rb");
    if (in_file == NULL) {
        std::cerr << "Can not open " << FILE_NAME << '\n';
        exit(8);
    }

    while (true) {
        ch = std::fgetc(in_file);
        if (ch == EOF)
            break;
        ++count;
    }
    std::cout << "Number of characters in " << FILE_NAME << 
        " is " << count << '\n';

    std::fclose(in_file);
    return (0);
}

A similar function, std::fputc, exists for writing a single character. Its format is:

std::fputc(character,  file); 

The functions std::fgets and std::fputs work on one line at a time. The format of the std::fgets call is:

line_ptr = std::fgets(line, size, file); 
line_ptr

Equal to line if the read was successful, or NULL if EOF or an error is detected.

line

A character array where the function places the line.

size

The size of the character array. std::fgets reads until it gets a line (complete with ending \n) or it reads size - 1 characters. It then ends the string with a null (\0).

For example:

        char    line[100]; 
        . . . 
        std::fgets(line, sizeof(line), in_file); 

std::fputs is similar to std::fgets except that it writes a line instead of reading one. The format of the std::fputs function is:

line_ptr = std::fputs(line, file); 

The parameters to std::fputs are similar to the ones for std::fgets. std::fputs needs no size because it gets the size of the line to write from the length of the line. (It keeps writing until it hits a null character, '\0').

The C++ function getline reads and discards the end-of-line character ('\n'). The C std::fgets reads the entire line, including the end-of-line and stores it in the buffer. So the '\n' is put in the buffer when you use std::fgets. This can sometimes cause surprising results.

    I l@ve RuBoard Previous Section Next Section