Home

 › 

Articles

 › 

Understanding File Handling in C++, With Examples

C++ vs. JavaScript

Understanding File Handling in C++, With Examples

Key Points

  • File handling in C++ involves managing, creating, reading, and writing files using the programming language.
  • The main classes used for file handling in C++ are ifstream, ofstream, and fstream.
  • File handling operations in C++ include writing formatted data, checking stream state, setting precision and width, reading lines of text, and opening and closing files.
  • An example code block demonstrates how to open, write to, and read from a file in C++.
  • Understanding file handling in C++ allows for efficient file manipulation and integration with other systems.

Computers provide us with a lot of ways to handle files and manipulate data. But when you’re programming, you often want a finer level of control and customization over your files. And when you’re working with large amounts of data, some programs can introduce unnecessary overheads and impair performance. These are situations where you may need a more robust technique, especially if you’re developing a program. In this article, we’re going to explore the elements involved in file handling in C++, including the operations used and best practices.

What Is File Handling in C++?

You may guess that file handling refers to the process involved in managing, creating, reading, and writing files, and you’d be absolutely right. As such, file handling in C++ is where we use the programming language to manipulate our files of data. This is usually preferable when developing a C++ project and vast amounts of data, as we can work quickly in the same language we’re developing in. C++ provides us with a lot of classes that can be used for handling files. We’ll get into the basics behind these next.

Classes for File Handling

The main classes used for handling files in C++ are ifstream, ofstream, and fstream. Usually, when we’re working with C++, we import the iostream header file, as this is needed for all standard input/output operations. However, when we want to manage files, we go one step further and import the fstream class as well. This provides us with specific classes to manipulate files effectively. We’ve summarized the class hierarchy and class functions in the following table:

ClassFunctionDerived fromExtends toOperations
iostreamHeader file, provides basic input/output operationsNoneNone<< and >> operators, tie(), flush()
iosBase class, provides functionality for istream and ostreamNoneistream, ostreamgood(), bad(), fail(), clear(), setstate(), precision(), width()
istreamBase class for input stream, used for reading filesiostreamNonegetline(), ignore(), peek(), get(), open(), close()
ostreamBase class for output stream, used for writing filesiostreamNoneput(), write(), open(), close()
fstreambaseBase class, with functionality for file streams specifically, i.e. opening and closing and error handlingiostreamifstream, ofstream, fstreamNone
ifstreamUsed to read data from files. Typically inherits istream and adds specific functionalityfstreambaseNoneSame as istream, but has opening functionality as well
ofstreamUsed for writing data to files. Inherits from ostream and adds specific functionalityfstreambaseNoneSame as ostream, but has opening functionality as well
fstreamUsed for reading and writing data to files. Inherits from istream and ostream, and adds specific functionalityfstreambaseNoneSame as istream and ostream, but has opening functionality as well
streambufInterface for handling stream buffers, i.e. managing data storage and transfer.iosNonesputc(), sgetc(), sputn(), sgetn()
filebufInterface between file and stream buffers.iosNoneSame as streambuf, but has opening and closing functionality as well
Function Overloading in C++
We use specific classes for file operations in C++.

©Monstar Studio/Shutterstock.com

File Handling Operations

There’s a brief overview of the operations involved in the previous table, but the following provides some more detail on how these work.

OperationUse
<<Overloaded operator, writes formatted data to an output stream.
>>Overloaded operator, reads formatted data from an input stream.
tie()Gets or sets the tied stream object, i.e. an input or output stream that’s synchronized with another stream.
flush()Flushes an output sequence, meaning the data is written immediately to the output destination.
good()Checks if stream state is good, and returns true if so.
bad()Checks if stream state is bad, and returns true if so.
fail()Checks if a failure has occurred, and returns true if so.
clear()Clears error flags and resets stream state.
setstate()Manually sets error flags.
precision()Sets number of decimal digits to display in an output.
width()Sets field width for output, i.e. the minimum number of characters to be written.
getline()Reads a line of text from an input stream until it reaches a newline.
ignore()Ignores a specific number of characters from an input stream.
peek()Returns next character of input stream without removing it.
get()Extracts single character from an input stream and increments the stream position.
open()Opens a file for reading or writing.
close()Closes a file.
put()Writes a character to the output stream.
write()Writes a block of data to the output stream, usually a specified number of characters.
sputc()Writes a single character to the output buffer.
sgetc()Reads a single character from the input buffer.
sputn()Writes a block of characters to the output buffer, using a pointer to the buffer and a specified number of characters.
sgetn()Reads a block of characters from the input buffer, using a pointer to the buffer and specified number of characters.

Example of Operations

Now that we’ve gone over the basic operations and classes involved in file handling, let’s illustrate some of them with an example. Consider this code block:

#include <iostream>
#include <fstream>
#include <string>

int main() {
    std::ofstream file("data.txt");

    if (file.is_open()) {
        std::string message = "Hello, World!";
        int number = 42;

        file.precision(2);
        file.width(10);

        file.tie(&std::cout);

        file << "Message: " << message << std::endl;
        file << "Number: " << number << std::endl;

        file.flush();

        if (file.good()) {
            std::cout << "File write operation was successful." << std::endl;
        } else {
            std::cout << "File write operation failed." << std::endl;
        }

        file.close();
    } else {
        std::cout << "Failed to open the file." << std::endl;
        return 1;
    }

    std::ifstream inputFile("data.txt");

    if (inputFile.is_open()) {
        char character;
        std::string line;

        character = inputFile.get();
        std::cout << "Character: " << character << std::endl;

        inputFile.clear();

        inputFile.ignore(4);
        character = inputFile.get();
        std::cout << "Next Character: " << character << std::endl;

        inputFile.seekg(0);
        character = inputFile.peek();
        std::cout << "Peeked Character: " << character << std::endl;

        inputFile.ignore(std::numeric_limits<std::streamsize>::max(), 'n');
        std::getline(inputFile, line);
        std::cout << "Line: " << line << std::endl;

        inputFile.close();
    } else {
        std::cout << "Failed to open the file for reading." << std::endl;
        return 1;
    }

    return 0;
}
Two programmers doing high five hand gesture at desk with multiple screens running code celebrating successful algorithm. Software developers colleagues enjoying teamwork results in it agency
You can manage files directly from your IDE using C++.

©DC Studio/Shutterstock.com

Explanation of Code

First, we import the necessary modules — “iostream” for input/output operations, “fstream” for file operations, and “string” for manipulating strings.

Opening the File, and Declaring Variables

Next, we declare the “main()” method, which declares an object called “file”, and opens a truncated file called “data.txt” in write mode. We then check if the file was opened successfully using “is_open()”.

After this, we declare the “message” string variable, assigning the “Hello, World!” value to it, and the “number” integer variable, assigning the value of 42. We also set the decimal values to 2 using “precision()” and the width to 10 using “width()”.

“tie()” is then used to synchronize the “file” stream with the “std::cout” stream, meaning that when we write to “file”, we also write to “std::cout”.

Writing the Message

The “<<” is used after that to write the message and number to the file. The output buffer is then flushed to make sure the data is written.

A check is then performed to make sure the state of the file is good and the operation was finished successfully. The message is also printed to indicate this, and the file is closed.

We then declare a new object of the “std::fstream” stream, called “inputFile”. We also open this file in read mode. The opening of the file is checked. The “character” and “line” variables are also declared.

Reading and Printing

“get()” is used to read a single character from the file, which is stored in the character variable and printed. Any potential error flags are also cleared using the “clear()” method.

The next 4 characters are ignored using “ignore()”, and then the next character is printed using “get()”.

After this, the position is moved to the beginning of the file with “seekg()” and the next character is printed using “peek()”. All remaining characters are then ignored until a newline is reached, and “getline()” is used to read the entire line, which is stored in the line variable and printed.

Lastly, the file is closed. The output can be seen in the accompanying image.

example of file handling operations in C++
Simple example of file handling operations in C++, with the expected output.

©History-Computer.com

Wrapping Up

There are many operations involved with file handling in C++. By understanding these, you can read and write files efficiently, as well as process files line by line and store data persistently. It’s important to check the file state and return error codes to handle any issues that arise effectively. Gaining an appreciation for file handling will also help you integrate your data with other systems, making it more robust.

Frequently Asked Questions

What classes are used to handle files in C++?

To handle files in C++, we mostly use three classes — ifstream, ofstream, and fstream. These have functionality specific to files, and can be used to create, read, and write files.

How do I open a file in C++?

You can open a file using the “ifstream” class or the “ofstream” class, depending on whether you want to read or write the file. The appropriate mode also needs to be used, i.e. “in” or “out”.

How do I check if opening a file was successful?

You can use the “is_open()” function on the stream object. It’ll return “true” if it was successfully opened.

How do I close a file in C++?

You can close a file using the “close()” function on the stream object, which will close the file and release the resources used.

What functions can be used to read data from a file?

You can use “getline()”, “get()”, or the “>>” operator to read data into the data type you wish.

What functions can be used to write data to a file?

You can use the “>>” operator or the “put()” or “write()” methods to write to a file.

 

How can I check if an operation was successfully completed?

You can check the object state using the “good()” function, which will return “true” if the operation has completed.

How are errors in file handling managed?

You can handle errors by checking the object state after every operation, and by displaying an error message or closing the file. You may want to use exception handling to catch any issues.

Can binary files be handled in C++?

Yes, you can perform input and output operations on binary files, but it’s a good idea to consider any issues that may arise depending on the platform you’re using.

What are the advantages of working with binary files?

Binary files require less memory space to store data than other forms of data. You can also use binary files to work with class objects, or other types of structured data.

To top