PYnative

Python Programming

  • Learn Python
    • Python Tutorials
    • Python Basics
    • Python Interview Q&As
  • Exercises
  • Quizzes
  • Code Editor
Home » CPP Exercises » C++ File Handling Exercises

C++ File Handling Exercises

Updated on: December 10, 2025 | Leave a Comment

C++ File Handling is a critical skill for managing persistent data, application logging, and complex data processing.

This comprehensive guide provides 25 practical C++ File Handling Exercises, designed to advance your skills from simple text I/O to advanced binary data files and custom structures.

Each exercise provides a clear problem statement, a helpful hint, a complete C++ solution, and a detailed explanation, ensuring you not only solve the problem but deeply understand why the solution works

+ Table Of Contents

Table of contents

  • Exercise 1: Create and Write
  • Exercise 2: Read and Display
  • Exercise 3: Append to File
  • Exercise 4: Count Characters
  • Exercise 5: Count Lines
  • Exercise 6: Copy File
  • Exercise 7: Check File Existence
  • Exercise 8: Clear File Content
  • Exercise 9: Word Counter
  • Exercise 10: Line Numbering
  • Exercise 11: Simple Search
  • Exercise 12: Case Conversion
  • Exercise 13: Data Storage (Integers)
  • Exercise 14: Data Retrieval (Average)
  • Exercise 15: Filtering Lines
  • Exercise 16: Log File Creator
  • Exercise 17: Reverse File Content (Line by Line)
  • Exercise 18: Structure I/O (Text)
  • Exercise 19: Structure Retrieval (Text)
  • Exercise 20: Binary Write (Integers)
  • Exercise 21: Binary Read (Integers)
  • Exercise 22: Update Record (Binary)
  • Exercise 23: File Size
  • Exercise 24: Random Access Read
  • Exercise 25: Exception Handling

What You’ll Practice

The coding challenges covers the following core file handling topics:

  • Basic I/O: Reading, writing, appending, and closing text files using fstream, ifstream, and ofstream.
  • Sequential Access & Parsing: Handling content line-by-line (std::getline), and parsing delimited data using std::stringstream.
  • Text Processing: Counting elements, searching, filtering, and case conversion.
  • Data Structures & Binary I/O: Reading and writing user-defined structures and raw bytes using Binary I/O (read() and write()).
  • Advanced Control: Implementing Random Access with seekg()/seekp() and robust Error Handling (is_open()).

Exercise 1: Create and Write

Problem Statement: Problem Statement Write a program to create a new text file named mydata.txt. Open the file for output and write the single line of text Hello, File Handling! into it. Ensure the program handles the closing of the file stream properly.

Expected Output:

Successfully wrote data to mydata.txt

mydata.txt File content:
Hello, File Handling!
+ Hint
  • Use the std::ofstream class, which is specialized for writing to files.
  • The file is created automatically if it does not exist when you declare the ofstream object with the filename.
  • You can use the insertion operator << just like you do with std::cout.
+ Show Solution
#include <fstream>
#include <iostream>
#include <string>

int main() {
    // 1. Declare an output file stream object
    std::ofstream outFile;

    // 2. Open the file (creates it if it doesn't exist)
    outFile.open("mydata.txt");

    // 3. Check if the file was successfully opened
    if (outFile.is_open()) {
        // 4. Write data to the file
        outFile << "Hello, File Handling!" << std::endl;
        std::cout << "Successfully wrote data to mydata.txt" << std::endl;

        // 5. Close the file stream
        outFile.close();
    } else {
        std::cerr << "Unable to open file mydata.txt" << std::endl;
    }

    return 0;
}Code language: C++ (cpp)
Run

Explanation:

  • This exercise introduces the file writing: std::ofstream. We declare an object, outFile, and call its open() method with the desired filename.
  • The crucial step is the error check using is_open(); if this fails, the program reports an error.
  • The output is written using the standard stream insertion operator <<.
  • Finally, outFile.close() is called to flush any remaining buffer data and release the file handle back to the operating system.

Exercise 2: Read and Display

Problem Statement: Read the entire content from the existing file mydata.txt (created in Exercise 1) and display it line by line on the console. Report an error if the file cannot be opened.

Expected Output:

--- Content of mydata.txt ---
Hello, File Handling!
+ Hint
  • Use the std::ifstream class for reading.
  • A common way to read line by line is to use the std::getline() function, which takes the file stream and a std::string variable as arguments, and reads until a newline character is encountered.
+ Show Solution
#include <fstream>
#include <iostream>
#include <string>

int main() {
    // 1. Declare an input file stream object
    std::ifstream inFile("mydata.txt"); 
    std::string fileLine;

    // 2. Check if the file was successfully opened
    if (inFile.is_open()) {
        std::cout << "--- Content of mydata.txt ---" << std::endl;
        
        // 3. Read the file line by line
        while (std::getline(inFile, fileLine)) {
            // 4. Display the read line
            std::cout << fileLine << std::endl;
        }

        // 5. Close the file stream
        inFile.close();
    } else {
        // 6. Report error if file opening failed
        std::cerr << "Error: Unable to open file mydata.txt for reading." << std::endl;
    }

    return 0;
}Code language: C++ (cpp)
Run

Explanation:

The std::ifstream object, inFile, is used to read the data.

The core reading loop uses while (std::getline(inFile, fileLine)). The std::getline() function attempts to read an entire line into the fileLine string. This function returns a reference to the stream object, which evaluates to true if the read was successful and false (terminating the loop) if the end-of-file (EOF) is reached or an error occurs. This is the idiomatic way to process text files line by line in C++.

Exercise 3: Append to File

Problem Statement: Write a program to open the existing file mydata.txt and append the line This is the appended text. to the end of the file. The original content should remain intact.

Expected Output:

Successfully appended text to mydata.txt

mydata.txt content:
Hello, File Handling!
This is the appended text.
+ Hint

When opening the file using std::ofstream, you need to specify the append file mode using std::ios::app. This ensures that any new data written will be placed at the current end of the file.

+ Show Solution
#include <fstream>
#include <iostream>

int main() {
    // 1. Declare an output file stream and open in append mode
    std::ofstream outFile("mydata.txt", std::ios::app);

    // 2. Check for successful opening
    if (outFile.is_open()) {
        // 3. Append the new line
        outFile << "This is the appended text." << std::endl;
        std::cout << "Successfully appended text to mydata.txt" << std::endl;

        // 4. Close the file stream
        outFile.close();
    } else {
        std::cerr << "Unable to open file mydata.txt for appending." << std::endl;
    }

    return 0;
}Code language: C++ (cpp)
Run

Explanation:

  • The key change here is the use of the second argument in the ofstream constructor: std::ios::app. This file mode flag modifies the behavior of the stream so that all output operations are performed at the end of the file, preserving the previous content.
  • If this flag were omitted, the default behavior would be to truncate (delete) the file content and start writing from the beginning.

Exercise 4: Count Characters

Problem Statement: Read the content of the file mydata.txt and count the total number of characters it contains. Display the final count on the console. Newline characters should also be counted.

Expected Output:

Total number of characters in mydata.txt: 49
+ Hint
  • Read the file character by character using the get() method of the ifstream object.
  • The loop continues as long as the stream is successfully reading characters.
+ Show Solution
#include <fstream>
#include <iostream>

int main() {
    std::ifstream inFile("mydata.txt");
    char character;
    int charCount = 0;

    if (inFile.is_open()) {
        // Read character by character until the end of the file
        while (inFile.get(character)) {
            charCount++;
        }

        std::cout << "Total number of characters in mydata.txt: " << charCount << std::endl;
        inFile.close();
    } else {
        std::cerr << "Error: Unable to open file." << std::endl;
    }

    return 0;
}Code language: C++ (cpp)
Run

Explanation:

  • This program uses a while loop with inFile.get(character). The get() method attempts to extract a single character (including whitespace and newline characters) and store it in the character variable.
  • If the extraction is successful, the stream object evaluates to true, the loop continues, and the charCount is incremented. When the end of the file is reached or an error occurs, the stream evaluates to false, and the loop terminates.

Exercise 5: Count Lines

Problem Statement: Read the content of the file mydata.txt and count the total number of lines present in the file. Display the final count on the console. An empty file should have a line count of 0.

Expected Output:

Total number of lines in mydata.txt: 2
+ Hint
  • Use the std::getline() function within a loop.
  • Since getline() reads until a newline, every successful call to it represents one line counted.
+ Show Solution
#include <fstream>
#include <iostream>
#include <string>

int main() {
    std::ifstream inFile("mydata.txt");
    std::string line;
    int lineCount = 0;

    if (inFile.is_open()) {
        // Use getline() to read line by line
        while (std::getline(inFile, line)) {
            lineCount++;
        }

        std::cout << "Total number of lines in mydata.txt: " << lineCount << std::endl;
        inFile.close();
    } else {
        std::cerr << "Error: Unable to open file." << std::endl;
    }

    return 0;
}Code language: C++ (cpp)
Run

Explanation:

  • This solution leverages the behavior of std::getline(). Each time std::getline() successfully reads a sequence of characters up to a newline and stores it in the line string, the lineCount is incremented.
  • The loop naturally terminates when the end of the file is reached. This is the most efficient and standard way to count lines in a text file using C++ streams.

Exercise 6: Copy File

Problem Statement: Write a program that copies the content of a file named source.txt to a new file called destination.txt. Both files must be handled correctly, including opening and closing the streams.

Expected Output:

File copied successfully from mydata.txt to destination.txt

destination.txt content:
Hello, File Handling!
This is the appended text.
+ Hint
  • You will need two file stream objects: an std::ifstream for reading the source and an std::ofstream for writing to the destination.
  • Use a while loop and std::getline() to transfer data line by line.
+ Show Solution
#include <fstream>
#include <iostream>
#include <string>

int main() {
    std::ifstream sourceFile("mydata.txt");
    std::ofstream destFile("destination.txt");
    std::string line;

    // Check if both files opened successfully
    if (sourceFile.is_open() && destFile.is_open()) {
        // Read from source line by line and write to destination
        while (std::getline(sourceFile, line)) {
            destFile << line << std::endl;
        }

        std::cout << "File copied successfully from mydata.txt to destination.txt" << std::endl;

        sourceFile.close();
        destFile.close();
    } else if (!sourceFile.is_open()) {
        std::cerr << "Error: Could not open mydata.txt." << std::endl;
    } else {
        std::cerr << "Error: Could not create/open destination.txt." << std::endl;
    }

    return 0;
}Code language: C++ (cpp)
Run

Explanation:

This program demonstrates simultaneous input and output file handling.

  • The condition if (sourceFile.is_open() && destFile.is_open()), ensuring both operations are possible before proceeding.
  • The while loop reads a line from the source file using getline() and immediately writes that line to the destination file using the stream insertion operator <<.
  • Note that std::endl is written explicitly to the destination file, as getline() consumes the newline character from the input stream.

Exercise 7: Check File Existence

Problem Statement: Ask the user to enter a filename. Write a program to check if the specified file exists and can be opened for reading. Output a clear message indicating whether the file was found or not.

Expected Output:

Enter the filename to check: mydata.txt
SUCCESS: File 'mydata.txt' was found and opened successfully.
+ Hint
  • Attempt to open the file using std::ifstream.
  • If the file exists and the program has permission to read it, the stream object’s is_open() method will return true.
+ Show Solution
#include <fstream>
#include <iostream>
#include <string>

int main() {
    std::string filename;
    std::cout << "Enter the filename to check: ";
    std::cin >> filename;

    // Attempt to open the file for reading
    std::ifstream testFile(filename);

    // Check the state of the stream
    if (testFile.is_open()) {
        std::cout << "SUCCESS: File '" << filename << "' was found and opened successfully." << std::endl;
        testFile.close(); // Close immediately as we only checked existence
    } else {
        std::cout << "FAILURE: File '" << filename << "' was not found or could not be opened." << std::endl;
    }

    return 0;
}Code language: C++ (cpp)
Run

Explanation:

  • The program takes the filename from the user and attempts to construct an std::ifstream object.
  • C++ file streams implicitly attempt to open the file during construction. By immediately calling is_open() on the testFile object, we can reliably determine if the operating system successfully located and granted read access to the file. This is the simplest and most common method for checking file existence in C++.

Exercise 8: Clear File Content

Problem Statement: Write a program that effectively clears all content from an existing file named destination.txt without deleting the file itself.

Expected Output:

File 'destination.txt' content has been cleared (truncated).
Verification: File is now empty.
+ Hint

Opening an std::ofstream without specifying any special mode flags (like std::ios::app) automatically uses the default output mode, which includes the truncate flag (std::ios::trunc). This mode deletes the file’s previous content upon opening.

+ Show Solution
#include <fstream>
#include <iostream>

int main() {
    // 1. The default mode for ofstream includes std::ios::trunc
    std::ofstream clearFile("destination.txt"); 

    if (clearFile.is_open()) {
        // 2. Closing the file without writing anything clears the content
        clearFile.close(); 
        std::cout << "File 'destination.txt' content has been cleared (truncated)." << std::endl;
    } else {
        std::cerr << "Error: Could not open/clear file 'destination.txt'." << std::endl;
    }
    
    // Optional: Re-open in read mode to verify it's empty
    std::ifstream checkFile("destination.txt");
    if (checkFile.peek() == std::ifstream::traits_type::eof()) {
        std::cout << "Verification: File is now empty." << std::endl;
    }

    return 0;
}Code language: C++ (cpp)
Run

Explanation:

  • The core trick here lies in the default behavior of std::ofstream. When you declare and open std::ofstream clearFile("destination.txt"), the file is automatically opened with the std::ios::out and std::ios::trunc flags.
  • The std::ios::trunc flag means “truncate the file to zero length upon opening.” By opening the file and immediately closing it without writing any data, we achieve the goal of clearing its content while keeping the file structure intact.

Exercise 9: Word Counter

Problem Statement: Read a file named mydata.txt and count the total number of words it contains. Assume that words are separated by any form of whitespace (spaces, newlines, tabs). Display the final word count.

Expected Output:

Total number of words in mydata.txt: 8
+ Hint
  • The stream extraction operator >> is designed to skip leading whitespace and read a single, non-whitespace sequence into a std::string variable.
  • Using this operator in a loop is the most idiomatic way to count words.
+ Show Solution
#include <fstream>
#include <iostream>
#include <string>

int main() {
    std::ifstream inFile("mydata.txt");
    std::string word;
    int wordCount = 0;

    if (inFile.is_open()) {
        // Loop uses the stream extraction operator (>>)
        while (inFile >> word) {
            wordCount++;
        }

        std::cout << "Total number of words in mydata.txt: " << wordCount << std::endl;
        inFile.close();
    } else {
        std::cerr << "Error: Unable to open mydata.txt." << std::endl;
    }

    return 0;
}Code language: C++ (cpp)
Run

Explanation:

  • Unlike std::getline(), which reads up to a newline, the stream extraction operator >> automatically handles delimiting data by whitespace.
  • When used in a while loop with a file stream, it repeatedly attempts to extract the next word (non-whitespace sequence) into the word variable.
  • Each successful extraction increments wordCount, providing an elegant and concise way to count words regardless of whether they are separated by spaces, tabs, or newlines.

Exercise 10: Line Numbering

Problem Statement: Read the content of mydata.txt line by line and write the content to a new file, numbered_output.txt. Each line in the output file must be prepended with its 1-based line number, followed by a colon and a space (e.g., “1: First line of text”).

Expected Output:

Successfully numbered lines into numbered_output.txt

numbered_output.txt content:
1: Hello, File Handling!
2: This is the appended text.
+ Hint
  • You will need two stream objects (ifstream and ofstream) and an integer variable initialized to 1 to track the line number.
  • Use std::getline() to read the input file.
+ Show Solution
#include <fstream>
#include <iostream>
#include <string>

int main() {
    std::ifstream inFile("mydata.txt");
    std::ofstream outFile("numbered_output.txt");
    std::string line;
    int lineNumber = 1;

    if (inFile.is_open() && outFile.is_open()) {
        while (std::getline(inFile, line)) {
            // Write line number, colon, and the line content to the output file
            outFile << lineNumber << ": " << line << std::endl;
            lineNumber++;
        }

        std::cout << "Successfully numbered lines into numbered_output.txt" << std::endl;
        inFile.close();
        outFile.close();
    } else {
        std::cerr << "Error: Failed to open one or both files." << std::endl;
    }

    return 0;
}Code language: C++ (cpp)
Run

Explanation:

  • This exercise reinforces the use of std::getline() for sequential line processing.
  • Inside the while loop, the current line number is written to the output stream first, followed by the delimiter “: “ and the actual content stored in the line string. The use of std::endl ensures that each numbered entry occupies its own line in the output file.
  • The lineNumber variable is incremented at the end of each iteration.

Exercise 11: Simple Search

Problem Statement: Ask the user for a word (a search key). Read a file named mydata.txt and determine if the search key exists anywhere within the file. Report the result (found or not found) to the user.

Expected Output:

Enter the word to search for: Hello
SUCCESS: The word 'Hello' was found in the document.
+ Hint

Read the file line by line using std::getline(). For each line, use the std::string::find() method, which returns std::string::npos if the substring is not found.

+ Show Solution
#include <fstream>
#include <iostream>
#include <string>

int main() {
    std::ifstream inFile("mydata.txt");
    std::string searchKey;
    std::string line;
    bool found = false;

    std::cout << "Enter the word to search for: ";
    std::cin >> searchKey;

    if (inFile.is_open()) {
        while (std::getline(inFile, line)) {
            // Check if the searchKey exists within the current line
            if (line.find(searchKey) != std::string::npos) {
                found = true;
                break; // Stop searching once found
            }
        }
        
        inFile.close();
        
        if (found) {
            std::cout << "SUCCESS: The word '" << searchKey << "' was found in the document." << std::endl;
        } else {
            std::cout << "NOT FOUND: The word '" << searchKey << "' was not present." << std::endl;
        }
    } else {
        std::cerr << "Error: Unable to open mydata.txt." << std::endl;
    }

    return 0;
}Code language: C++ (cpp)
Run

Explanation:

  • This solution combines file reading with string manipulation. The std::string::find(searchKey) method performs the core logic. If the substring is found, find() returns the starting position (an index), which is never equal to std::string::npos (a constant representing “not a position”).
  • Once the word is found, the found flag is set to true, and break immediately exits the loop, optimizing performance by not reading the rest of the file.

Exercise 12: Case Conversion

Problem Statement: Read the content of a file named mydata.txt and write all its content to a new output file, uppercase.txt, converting every letter to uppercase. Non-alphabetic characters should remain unchanged.

Expected Output:

Content successfully converted to uppercase and saved to uppercase.txt

uppercase.txt Content:
HELLO, FILE HANDLING!
THIS IS THE APPENDED TEXT.
+ Hint
  • Read the file character by character using get().
  • Use the std::toupper() function (from the <cctype> header) on each character before writing it to the output file.
+ Show Solution
#include <fstream>
#include <iostream>
#include <cctype> // Required for std::toupper

int main() {
    std::ifstream inFile("mydata.txt");
    std::ofstream outFile("uppercase.txt");
    char character;

    if (inFile.is_open() && outFile.is_open()) {
        // Read character by character
        while (inFile.get(character)) {
            // Convert character to uppercase and write to the output file
            outFile.put(static_cast<char>(std::toupper(character)));
        }

        std::cout << "Content successfully converted to uppercase and saved to uppercase.txt" << std::endl;
        inFile.close();
        outFile.close();
    } else {
        std::cerr << "Error: Failed to open one or both files." << std::endl;
    }

    return 0;
}Code language: C++ (cpp)
Run

Explanation:

  • This program uses a character-by-character approach for detailed manipulation. inFile.get(character) reads every byte.
  • The core transformation is done by std::toupper(character), which converts the character to uppercase if it’s a lowercase letter, and returns the character unchanged otherwise.
  • outFile.put() is used to write a single character back to the file. The static_cast<char> is necessary because std::toupper() returns an int (representing the character’s ASCII/Unicode value).

Exercise 13: Data Storage (Integers)

Problem Statement: Ask the user to enter five integer values. Write these five numbers, each on a separate line, into a file named numbers.txt.

Expected Output:

Enter five integers (press Enter after each):
Integer 1: 10
Integer 2: 20
Integer 3: 30
Integer 4: 40
Integer 5: 50
Five integers successfully written to numbers.txt.
+ Hint
  • Use a for loop to iterate five times, prompting the user for input using std::cin inside the loop.
  • Use std::ofstream and the insertion operator << to write the number followed by std::endl.
+ Show Solution
#include <fstream>
#include <iostream>

int main() {
    std::ofstream outFile("numbers.txt");
    int number;

    if (outFile.is_open()) {
        std::cout << "Enter five integers (press Enter after each):" << std::endl;
        
        for (int i = 0; i < 5; ++i) {
            std::cout << "Integer " << (i + 1) << ": ";
            std::cin >> number;
            
            // Write the number followed by a newline
            outFile << number << std::endl;
        }

        outFile.close();
        std::cout << "Five integers successfully written to numbers.txt." << std::endl;
    } else {
        std::cerr << "Error: Could not open numbers.txt for writing." << std::endl;
    }

    return 0;
}Code language: C++ (cpp)
Run

Explanation:

  • This exercise is a straightforward application of std::ofstream combined with basic user input.
  • The for loop controls the number of inputs taken.
  • Inside the loop, the input is read into the number variable using std::cin, and then written to the file using outFile << number << std::endl. Using std::endl ensures that each integer is stored on its own line.

Exercise 14: Data Retrieval (Average)

Problem Statement: Read the integers stored in numbers.txt (created in Exercise 13). Calculate the sum and the average of all the numbers in the file. Display both the sum and the average.

Expected Output:

Total numbers read: 5
Sum of numbers: 150
Average of numbers: 30.00
+ Hint
  • Use a std::ifstream object and the extraction operator >> within a while loop to read integers.
  • Keep track of the total sum and the count of numbers read to calculate the average.
+ Show Solution
#include <fstream>
#include <iostream>
#include <iomanip> // For std::fixed and std::setprecision

int main() {
    std::ifstream inFile("numbers.txt");
    int number;
    double sum = 0.0;
    int count = 0;

    if (inFile.is_open()) {
        // Read number by number until EOF
        while (inFile >> number) {
            sum += number;
            count++;
        }

        inFile.close();

        if (count > 0) {
            double average = sum / count;
            std::cout << "Total numbers read: " << count << std::endl;
            std::cout << "Sum of numbers: " << sum << std::endl;
            // Display average with two decimal places
            std::cout << std::fixed << std::setprecision(2);
            std::cout << "Average of numbers: " << average << std::endl;
        } else {
            std::cout << "The file numbers.txt is empty." << std::endl;
        }
    } else {
        std::cerr << "Error: Could not open numbers.txt for reading." << std::endl;
    }

    return 0;
}Code language: C++ (cpp)
Run

Explanation:

  • This solution uses the powerful feature of the stream extraction operator >> to read structured data. When reading from a file of numbers, the loop while (inFile >> number) handles parsing the text data into the integer number and automatically stops when the end of the file is reached or invalid data is encountered.
  • We track the sum and count to calculate the average, ensuring we check if count is greater than zero to avoid division by zero.

Exercise 15: Filtering Lines

Problem Statement: Read a file named log_data.txt. Write only the lines that start with the letter ‘H’ (case-insensitive) to a new file called filtered_log.txt.

Given:

log_data.txt Content:

Hello, File Handling!
This is the appended text.
hello, cpp File Handling!

Expected Output:

filtered_log.txt Content:

Hello, File Handling!
hello, cpp File Handling!
+ Hint
  • Read line by line using std::getline().
  • For each line, check if the line is not empty and if its first character, after converting it to uppercase using std::toupper(), is equal to ‘H’.
+ Show Solution
#include <fstream>
#include <iostream>
#include <string>
#include <cctype>

int main() {
    std::ifstream inFile("mydata.txt");
    std::ofstream outFile("filtered_log.txt");
    std::string line;

    if (inFile.is_open() && outFile.is_open()) {
        while (std::getline(inFile, line)) {
            // Check if the line is not empty AND starts with 'E' or 'e'
            if (!line.empty() && std::toupper(line[0]) == 'H') {
                outFile << line << std::endl;
            }
        }

        std::cout << "Filtering complete. Matching lines saved to filtered_log.txt" << std::endl;
        inFile.close();
        outFile.close();
    } else {
        std::cerr << "Error: Failed to open one or both files." << std::endl;
    }

    return 0;
}Code language: C++ (cpp)
Run

Explanation:

  • This exercise demonstrates conditional writing based on line content.
  • The check !line.empty() prevents an error if an empty line is encountered.
  • The core filtering logic is std::toupper(line[0]) == 'H'. By converting the first character line[0] to uppercase before comparison, the check becomes case-insensitive, matching lines that start with either ‘H’ or ‘h’. Only if the condition is true is the line written to the output file.

Exercise 16: Log File Creator

Problem Statement: Write a function named write_log(const std::string& message) that takes a string message and appends it to a file named system.log. The function must prepend the message with the current time and date in a simple format before writing it to the file.

Expected Output:

Log entries written to system.log

system.log Content:
[2025-11-01 06:54:41] Application started successfully.
[2025-11-01 06:54:41] User accessed database.
[2025-11-01 06:54:41] Error: Invalid login attempt detected.
+ Hint
  • Use the <ctime> header to get the current time. Specifically, use std::time(), std::localtime(), and std::put_time() (or std::strftime() for older compilers) to format the timestamp string.
  • Remember to open the file in append mode (std::ios::app).
+ Show Solution
#include <fstream>
#include <iostream>
#include <string>
#include <chrono> // For modern time handling
#include <ctime>  // For std::time_t, std::localtime
#include <iomanip> // For std::put_time

void write_log(const std::string& message) {
    // Open file in append mode
    std::ofstream logFile("system.log", std::ios::app);

    if (logFile.is_open()) {
        // Get current time
        auto now = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
        
        // Convert time to local structure
        // Note: localtime is generally thread-unsafe, use localtime_s/localtime_r in production
        std::tm* localTime = std::localtime(&now); 

        // Write the formatted timestamp
        logFile << "[" << std::put_time(localTime, "%Y-%m-%d %H:%M:%S") << "] ";

        // Write the user message and a newline
        logFile << message << std::endl;

        logFile.close();
    } else {
        // Output error to console if logging fails
        std::cerr << "CRITICAL: Log file writing failed!" << std::endl;
    }
}

int main() {
    write_log("Application started successfully.");
    write_log("User accessed database.");
    write_log("Error: Invalid login attempt detected.");
    std::cout << "Log entries written to system.log" << std::endl;
    return 0;
}Code language: C++ (cpp)
Run

Explanation:

This solution introduces basic date/time formatting for robust logging

  • The file is opened with std::ios::app to ensure new messages are always added to the end.
  • Time handling involves converting the current system time to a std::tm structure using std::localtime. std::put_time() is then used with the format string "%Y-%m-%d %H:%M:%S" to neatly format the timestamp directly into the output stream. The function successfully encapsulates the logging logic, making it reusable.

Exercise 17: Reverse File Content (Line by Line)

Problem Statement: Read all lines of a file named mydata.txt into an in-memory structure. Reverse the order of these lines and write them to a new file called reversed.txt. The last line of the original file should be the first line of the new file, and so on.

This exercise demonstrates intermediate data storage before output.

Expected Output:

Lines reversed and saved to reversed.txt

reversed.txt Content
hello, cpp File Handling!
This is the appended text.
Hello, File Handling!
+ Hint
  • Store the lines in a std::vector<std::string>.
  • Once all lines are read, iterate over the vector in reverse order (from the last element to the first) and write each string to the output file.
+ Show Solution
#include <fstream>
#include <iostream>
#include <string>
#include <vector>
#include <algorithm> // Not strictly necessary but useful for reverse()

int main() {
    std::ifstream inFile("mydata.txt");
    std::ofstream outFile("reversed.txt");
    std::string line;
    std::vector<std::string> lines;

    if (inFile.is_open() && outFile.is_open()) {
        // 1. Read all lines into the vector
        while (std::getline(inFile, line)) {
            lines.push_back(line);
        }
        inFile.close();
        
        // 2. Write lines to the output file in reverse order
        for (auto it = lines.rbegin(); it != lines.rend(); ++it) {
            outFile << *it << std::endl;
        }

        outFile.close();
        std::cout << "Lines reversed and saved to reversed.txt" << std::endl;
    } else {
        std::cerr << "Error: Failed to open files." << std::endl;
    }

    return 0;
}Code language: C++ (cpp)
Run

Explanation:

  • All content is first loaded into the lines vector.
  • The reversal logic uses reverse iterators: lines.rbegin() points to the last element of the vector, and lines.rend() points one past the first element.
  • Iterating from rbegin() to rend() effectively processes the vector from back to front, achieving the line reversal.

Exercise 18: Structure I/O (Text)

Problem Statement: Define a C++ structure named Person with private members: std::string name and int age. Implement a program that prompts the user for data for three people and writes their name and age, separated by a comma on the same line, into a text file named people_text.txt.

Expected Output:

Enter data for 3 people:
Person 1 Name: Jessa
Person 1 Age: 28
Person 2 Name: Jon
Person 2 Age: 35
Person 3 Name: Kerry
Person 3 Age: 30

Data successfully written to people_text.txt.
+ Hint
  • Use a struct or class to define Person.
  • Use a for loop to collect data for three instances.
  • Write the data using std::ofstream and ensure a delimiter (like a comma) separates the fields so they can be parsed later.
+ Show Solution
#include <fstream>
#include <iostream>
#include <string>
#include <vector>

struct Person {
    std::string name;
    int age;
};

int main() {
    std::ofstream outFile("people_text.txt");
    std::vector<Person> people(3);

    if (outFile.is_open()) {
        std::cout << "Enter data for 3 people:" << std::endl;
        for (int i = 0; i < 3; ++i) {
            std::cout << "Person " << (i + 1) << " Name: ";
            std::cin.ignore(); // Consume any leftover newline
            std::getline(std::cin, people[i].name);
            
            std::cout << "Person " << (i + 1) << " Age: ";
            std::cin >> people[i].age;
            
            // Write structured data as Name,Age
            outFile << people[i].name << "," << people[i].age << std::endl;
        }

        outFile.close();
        std::cout << "\nData successfully written to people_text.txt." << std::endl;
    } else {
        std::cerr << "Error: Could not open people_text.txt for writing." << std::endl;
    }
    return 0;
}Code language: C++ (cpp)
Run

Explanation:

  • The Person structure is defined to hold the related data.
  • We use std::getline(std::cin, ...) for the name to capture full names with spaces and std::cin >> ... for the age.
  • The data is written to the file using a comma as a separator, converting the structured data into a flat, readable text format. This design ensures the data can be correctly reconstructed (parsed).

Exercise 19: Structure Retrieval (Text)

Problem Statement: Read the structured, comma-separated data from people_text.txt (created in Exercise 18). Parse each line and reconstruct the data into a std::vector<Person>. Finally, display all the retrieved records on the console.

Expected Output:

--- Retrieved People Data ---
Name: Jessa, Age: 28
Name: Jon, Age: 35
Name: Kerry, Age: 30
+ Hint
  • Read the file line by line using std::getline(). For each line, use std::stringstream and std::getline(ss, field, ',') to separate the name and age.
  • Remember to convert the age string back into an integer using std::stoi().
+ Show Solution
#include <fstream>
#include <sstream>
#include <iostream>
#include <string>
#include <vector>

struct Person {
    std::string name;
    int age;
};

int main() {
    std::ifstream inFile("people_text.txt");
    std::vector<Person> retrievedPeople;
    std::string line, nameStr, ageStr;

    if (inFile.is_open()) {
        while (std::getline(inFile, line)) {
            std::stringstream ss(line);
            
            // Extract Name (field 1)
            std::getline(ss, nameStr, ',');
            // Extract Age (field 2)
            std::getline(ss, ageStr, ','); 

            Person p;
            p.name = nameStr;
            try {
                p.age = std::stoi(ageStr); // Convert string to integer
                retrievedPeople.push_back(p);
            } catch (const std::exception& e) {
                std::cerr << "Skipping malformed record: " << e.what() << std::endl;
            }
        }
        inFile.close();

        std::cout << "\n--- Retrieved People Data ---" << std::endl;
        for (const auto& p : retrievedPeople) {
            std::cout << "Name: " << p.name << ", Age: " << p.age << std::endl;
        }
    } else {
        std::cerr << "Error: Could not open people_text.txt for reading." << std::endl;
    }
    return 0;
}Code language: C++ (cpp)
Run

Explanation:

  • This solution is the inverse of the previous one.
  • It uses std::stringstream to break apart the comma-separated text into individual strings (nameStr and ageStr).
  • Since the age was stored as text, it must be converted back to its original type (int) using std::stoi() before being stored in the Person structure and added to the vector.

Exercise 20: Binary Write (Integers)

Problem Statement: Create an array of 5 integers. Write these 5 integers into a file named integers.bin in binary format. This means writing the raw memory representation of the integers, not their text form.

Expected Output:

Successfully wrote 5 integers in binary format to integers.bin
+ Hint
  • Use std::ofstream opened with the std::ios::binary flag.
  • The stream’s write() method is used for binary output. It requires a pointer to the start of the data buffer (cast to const char*) and the size of the data in bytes (sizeof(data)).
+ Show Solution
#include <fstream>
#include <iostream>

int main() {
    int data[] = {10, 255, 3000, 42, 99999};
    int count = sizeof(data) / sizeof(data[0]);

    // Open file in output and binary mode
    std::ofstream outFile("integers.bin", std::ios::out | std::ios::binary);

    if (outFile.is_open()) {
        // Write the entire array's raw memory content
        outFile.write(
            reinterpret_cast<const char*>(data), // Pointer to data, cast to const char*
            sizeof(data)                         // Total size of data in bytes
        );

        outFile.close();
        std::cout << "Successfully wrote " << count << " integers in binary format to integers.bin." << std::endl;
    } else {
        std::cerr << "Error: Could not open integers.bin for binary writing." << std::endl;
    }
    return 0;
}Code language: C++ (cpp)
Run

Explanation:

  • Binary file handling uses the | std::ios::binary flag. The outFile.write() method bypasses text formatting and writes the raw bytes directly from the memory location of the data array.
  • We use reinterpret_cast<const char*>() to safely convert the pointer type, a necessary step for C++ streams. The total number of bytes written is sizeof(data), which is 5 * sizeof(int).

Exercise 21: Binary Read (Integers)

Problem Statement: Read the 5 integers back from the binary file integers.bin (created in Exercise 23). Store them in a new integer array or vector and display them on the console to verify the data integrity.

Expected Output:

Successfully read 5 integers from integers.bin:
Data[0]: 10
Data[1]: 255
Data[2]: 3000
Data[3]: 42
Data[4]: 99999
+ Hint
  • Use std::ifstream opened with the std::ios::binary flag.
  • The stream’s read() method is used for binary input. It requires a pointer to the destination buffer (cast to char*) and the size of the data to read.
+ Show Solution
#include <fstream>
#include <iostream>
#include <vector>

int main() {
    std::vector<int> readData(5); // Prepare space for 5 integers
    size_t dataSize = readData.size() * sizeof(int);

    // Open file in input and binary mode
    std::ifstream inFile("integers.bin", std::ios::in | std::ios::binary);

    if (inFile.is_open()) {
        // Read the exact number of bytes into the vector's internal array
        inFile.read(
            reinterpret_cast<char*>(readData.data()), // Pointer to destination buffer
            dataSize                                 // Total size of data to read
        );

        inFile.close();

        // Check if the read operation was successful (read all bytes)
        if (inFile.gcount() == dataSize) {
            std::cout << "Successfully read " << readData.size() << " integers from integers.bin:" << std::endl;
            for (size_t i = 0; i < readData.size(); ++i) {
                std::cout << "Data[" << i << "]: " << readData[i] << std::endl;
            }
        } else {
            std::cerr << "Error: Did not read expected number of bytes. File may be corrupted/incomplete." << std::endl;
        }
    } else {
        std::cerr << "Error: Could not open integers.bin for binary reading." << std::endl;
    }
    return 0;
}Code language: C++ (cpp)
Run

Explanation:

  • This solution uses inFile.read() to retrieve the raw bytes.
  • The data is read directly into the memory allocated for the readData vector using readData.data() (which returns a pointer to the vector’s underlying array).
  • The gcount() method is essential in binary I/O; it returns the number of characters (bytes) successfully read by the last unformatted input operation, allowing us to verify the entire expected block of data was retrieved.

Exercise 22: Update Record (Binary)

Problem Statement: Define a structure Product containing int id and float price. Create a binary file products.bin with three initial product records. Then, write a program segment that uses seekp() and seekg() to find the second record (ID 2) and update its price in place without rewriting the entire file.

Expected Output:

Successfully updated price for record 2 to $75.25
+ Hint
  • The file stream must be opened in update mode (std::ios::in | std::ios::out | std::ios::binary).
  • The starting position of the second record is calculated as 1 * sizeof(Product). Use seekp() to move the put pointer (for writing) to the correct location.
+ Show Solution
#include <fstream>
#include <iostream>

struct Product {
    int id;
    float price;
};

int main() {
    // 1. Setup and initial write (for testing)
    Product products[] = {{1, 10.50f}, {2, 50.00f}, {3, 22.99f}};
    std::fstream file("products.bin", std::ios::out | std::ios::binary | std::ios::trunc);
    file.write(reinterpret_cast<const char*>(products), sizeof(products));
    file.close();

    // 2. Update operation
    float newPrice = 75.25f;
    int recordIndex = 1; // Index 1 for the second record (ID 2)
    size_t offset = recordIndex * sizeof(Product); // Byte offset to the start of record 2

    // Open file for reading AND writing (in/out) and binary mode
    file.open("products.bin", std::ios::in | std::ios::out | std::ios::binary);

    if (file.is_open()) {
        // Calculate offset to the price member (within the struct)
        // Offset = (Start of Record 2) + (Offset of 'price' member)
        size_t priceOffset = offset + sizeof(int); // 'price' starts after 'id' (4 bytes)

        // Move the write pointer (put pointer) to the start of the price field
        file.seekp(priceOffset, std::ios::beg);
        
        // Write the new price over the old one
        file.write(reinterpret_cast<const char*>(&newPrice), sizeof(newPrice));

        file.close();
        std::cout << "Successfully updated price for record 2 to $" << newPrice << std::endl;
    } else {
        std::cerr << "Error: Could not open products.bin for update." << std::endl;
    }
    return 0;
}Code language: C++ (cpp)
Run

Explanation:

  • This advanced exercise uses the std::fstream class for simultaneous reading and writing. The file is opened with std::ios::in | std::ios::out for update access.
  • The key is calculating the exact byte offset to the data to be modified. Since the price member is located after the id member (which takes sizeof(int) bytes), we move the put pointer (seekp()) to the start of the second record and then add sizeof(int) to land exactly on the price field. The new float value is then written, overwriting the old value.

Exercise 23: File Size

Problem Statement: Write a program that determines and outputs the size of a file named mydata.txt in bytes.

Expected Output:

The size of 'mydata.txt' is 63 bytes.
+ Hint
  • Use std::ifstream opened in binary mode.
  • To find the size, use the stream’s seekg() method to move the get pointer to the end of the file (std::ios::end), and then use tellg() to report the current position, which is the total file size in bytes
+ Show Solution
#include <fstream>
#include <iostream>
#include <string>

int main() {
    std::string filename = "mydata.txt";
    // Create a dummy file for testing if it doesn't exist
    std::ofstream temp(filename);
    temp << "A relatively long string of content to give the file some size.";
    temp.close();

    // Open the file in binary mode for accurate size calculation
    std::ifstream inFile(filename, std::ios::in | std::ios::binary);
    long fileSize = 0;

    if (inFile.is_open()) {
        // 1. Move the get pointer to the end of the file
        inFile.seekg(0, std::ios::end);
        
        // 2. Get the position of the pointer (which is the file size)
        fileSize = inFile.tellg();
        
        inFile.close();

        if (fileSize != -1) {
            std::cout << "The size of '" << filename << "' is " << fileSize << " bytes." << std::endl;
        } else {
            std::cerr << "Error: Could not determine file size." << std::endl;
        }
    } else {
        std::cerr << "Error: Could not open file " << filename << std::endl;
    }
    return 0;
}Code language: C++ (cpp)
Run

Explanation:

  • This technique is the standard way to determine file size in C++.
  • By opening the file and moving the get pointer to the end using inFile.seekg(0, std::ios::end) (offset 0 from the end), the pointer’s current location, retrieved by inFile.tellg(), corresponds exactly to the total number of bytes in the file.
  • The binary mode is used to prevent stream translators from altering the byte count due to character encoding.

Exercise 24: Random Access Read

Problem Statement: Read a text file named people_text.txt and display only the content that starts from the 8th character (index 8) up to the 20th character.

Expected Output:

--- Content from byte 8 to 20 ---
Jon,35
Kerry
+ Hint
  • Use std::ifstream.
  • Use seekg() to directly position the get pointer to the desired starting byte offset (10).
  • Then, read the next 11 characters using a loop or an array read.
+ Show Solution
#include <fstream>
#include <iostream>
#include <string>
#include <vector>

int main() {
    // Note: Ensure long_document.txt exists and is large enough (>= 100 bytes)
    std::ifstream inFile("people_text.txt", std::ios::binary); // Use binary for byte accuracy
    int startOffset = 8; // 50th character (0-based index)
    int bytesToRead = 12; // Read up to 20th character (8+12 = 20)

    if (inFile.is_open()) {
        // 1. Move the get pointer to the start offset
        inFile.seekg(startOffset, std::ios::beg);

        if (!inFile.fail()) {
            // 2. Prepare a buffer to read the chunk
            std::vector<char> buffer(bytesToRead + 1, '\0'); // +1 for null terminator

            // 3. Read the specified number of bytes
            inFile.read(buffer.data(), bytesToRead);

            std::cout << "--- Content from byte " << startOffset << " to " 
                      << startOffset + inFile.gcount() << " ---" << std::endl;
            // Output the read buffer (using gcount() for actual bytes read)
            std::cout.write(buffer.data(), inFile.gcount());
            std::cout << "\n----------------------------------------------------" << std::endl;
        } else {
            std::cerr << "Error: Failed to seek to position " << startOffset << std::endl;
        }

        inFile.close();
    } else {
        std::cerr << "Error: Could not open mydata.txt." << std::endl;
    }
    return 0;
}Code language: C++ (cpp)
Run

Explanation:

  • This is an example of random access I/O. Instead of reading sequentially, we use inFile.seekg(startOffset, std::ios::beg) to jump directly to byte 8 from the beginning (std::ios::beg). We then use the unformatted inFile.read() to extract the next 12 bytes directly into our buffer.
  • The std::cout.write() method is used to print the content of the buffer, utilizing inFile.gcount() to ensure only the bytes successfully read (in case EOF was hit early) are displayed.

Exercise 25: Exception Handling

Problem Statement: Modify a file reading program (like Exercise 2) to use C++ exception handling. Configure the stream to throw exceptions on failure, and wrap the file operations in a try-catch block to gracefully catch and report std::ios_base::failure if the file cannot be opened.

Expected Output:

--- FILE I/O EXCEPTION CAUGHT ---
File: nonexistent.txt
Reason: basic_ios::clear: iostream error
Code: Check if file exists or if permissions are correct.
+ Hint
  • Before attempting the file operation, use the stream’s exceptions() method to set the stream state flags (std::ios::failbit | std::ios::badbit) that should trigger an exception.
  • This forces the stream to throw instead of just setting an internal error flag.
+ Show Solution
#include <fstream>
#include <iostream>
#include <string>
#include <stdexcept>

int main() {
    std::string filename = "nonexistent.txt"; // A file guaranteed to fail opening

    try {
        std::ifstream inFile;
        
        // 1. Tell the stream to throw exceptions on failure/bad states
        inFile.exceptions(std::ios::failbit | std::ios::badbit);

        // 2. Attempt to open the file (may throw here)
        inFile.open(filename);

        // If open succeeded (unlikely for nonexistent.txt):
        std::string line;
        while (std::getline(inFile, line)) {
            std::cout << line << std::endl;
        }
        inFile.close();
        
    } catch (const std::ios_base::failure& e) {
        // 3. Catch the specific file stream exception
        std::cerr << "--- FILE I/O EXCEPTION CAUGHT ---" << std::endl;
        std::cerr << "File: " << filename << std::endl;
        std::cerr << "Reason: " << e.what() << std::endl;
        std::cerr << "Code: Check if file exists or if permissions are correct." << std::endl;
        return 1;
        
    } catch (const std::exception& e) {
        // Catch any other standard exceptions
        std::cerr << "Generic Error: " << e.what() << std::endl;
        return 1;
    }

    return 0;
}Code language: C++ (cpp)
Run

Explanation:

  • Standard C++ streams do not throw exceptions by default; they rely on checking internal state flags (fail(), bad()).
  • This exercise forces exception behavior by calling inFile.exceptions(std::ios::failbit | std::ios::badbit).
  • If the inFile.open(filename) call fails (because the file doesn’t exist), the stream immediately throws an object of type std::ios_base::failure. The try-catch block cleanly intercepts this error, allowing the program to report the failure without crashing.

Filed Under: CPP Exercises

Did you find this page helpful? Let others know about it. Sharing helps me continue to create free Python resources.

TweetF  sharein  shareP  Pin

About Vishal

Image

I’m Vishal Hule, the Founder of PYnative.com. As a Python developer, I enjoy assisting students, developers, and learners. Follow me on Twitter.

Related Tutorial Topics:

CPP Exercises

All Coding Exercises:

C Exercises
C++ Exercises
Python Exercises

Python Exercises and Quizzes

Free coding exercises and quizzes cover Python basics, data structure, data analytics, and more.

  • 15+ Topic-specific Exercises and Quizzes
  • Each Exercise contains 25+ questions
  • Each Quiz contains 25 MCQ
Exercises
Quizzes

Leave a Reply Cancel reply

your email address will NOT be published. all comments are moderated according to our comment policy.

Use <pre> tag for posting code. E.g. <pre> Your entire code </pre>

In: CPP Exercises
TweetF  sharein  shareP  Pin

  CPP Exercises

  • All C++ Exercises
  • C++ Exercise for Beginners
  • C++ Loops Exercise
  • C++ Functions Exercise
  • C++ Arrays Exercise
  • C++ String Exercise
  • C++ Pointers Exercise
  • C++ OOP Exercise
  • C++ File Handling Exercise
  • C++ Structures and Enums Exercise
  • C++ Templates and Generic Programming Exercise

All Coding Exercises

C Exercises C++ Exercises Python Exercises

About PYnative

PYnative.com is for Python lovers. Here, You can get Tutorials, Exercises, and Quizzes to practice and improve your Python skills.

Follow Us

To get New Python Tutorials, Exercises, and Quizzes

  • Twitter
  • Facebook
  • Sitemap

Explore Python

  • Learn Python
  • Python Basics
  • Python Databases
  • Python Exercises
  • Python Quizzes
  • Online Python Code Editor
  • Python Tricks

Coding Exercises

  • C Exercises
  • C++ Exercises
  • Python Exercises

Legal Stuff

  • About Us
  • Contact Us

We use cookies to improve your experience. While using PYnative, you agree to have read and accepted our:

  • Terms Of Use
  • Privacy Policy
  • Cookie Policy

Copyright © 2018–2025 pynative.com

Advertisement