Introduction
In this lab, you will learn how to perform various file operations in C++. The lab covers opening files for reading and writing, writing text data to files, reading data from text files, checking file open status, handling file read/write errors, working with binary files, positioning the file pointer, and closing files to release resources. You will gain practical experience in using the fundamental file stream classes ofstream and ifstream from the C++ standard library to interact with files. By the end of this lab, you will have a solid understanding of file handling in C++ programming.
Open Files Using ofstream and ifstream
In this step, you'll learn how to open files in C++ using two fundamental file stream classes: ofstream for writing files and ifstream for reading files. These classes are part of the C++ standard library and provide essential file handling capabilities.
First, navigate to the project directory in the WebIDE terminal:
cd ~/project
Create a new C++ file called file_operations.cpp:
touch file_operations.cpp
Add the following code to the file_operations.cpp file:
#include <iostream>
#include <fstream> // Include file stream header
int main() {
// Opening a file for writing using ofstream
std::ofstream outputFile("example.txt");
// Check if the file is successfully opened
if (outputFile.is_open()) {
std::cout << "File opened for writing successfully!" << std::endl;
outputFile.close(); // Close the file
} else {
std::cout << "Unable to open file for writing." << std::endl;
}
// Opening a file for reading using ifstream
std::ifstream inputFile("example.txt");
// Check if the file is successfully opened
if (inputFile.is_open()) {
std::cout << "File opened for reading successfully!" << std::endl;
inputFile.close(); // Close the file
} else {
std::cout << "Unable to open file for reading." << std::endl;
}
return 0;
}
Let's break down the key concepts:
#include <fstream>: Includes the file stream librarystd::ofstream: Output file stream for writing filesstd::ifstream: Input file stream for reading filesis_open(): Checks if the file was successfully openedclose(): Closes the file after operations
Compile the program:
g++ file_operations.cpp -o file_operations
Run the executable:
./file_operations
Example output:
File opened for writing successfully!
File opened for reading successfully!
Some important points about file streams:
- Always check if a file is successfully opened before performing operations
- Remember to close files after you're done using them
ofstreamis used for writing to filesifstreamis used for reading from files- Both classes are part of the
<fstream>header
You can think of file streams like opening and closing doors to files. ofstream lets you write into a room, while ifstream allows you to read what's inside.
Write Text Data to Files
In this step, you'll learn how to write text data to files using the ofstream class in C++. Building on the previous step, you'll explore different ways to write strings, numbers, and multiple lines to files.
Create a new C++ file called write_files.cpp:
touch ~/project/write_files.cpp
Add the following code to the write_files.cpp file:
#include <iostream>
#include <fstream>
#include <string>
int main() {
// Open a file for writing
std::ofstream outputFile("student_data.txt");
// Check if the file is successfully opened
if (outputFile.is_open()) {
// Writing a single string
outputFile << "John Doe" << std::endl;
// Writing multiple pieces of data
std::string name = "Alice Smith";
int age = 22;
double gpa = 3.75;
outputFile << name << ", " << age << " years old, GPA: " << gpa << std::endl;
// Writing multiple lines
outputFile << "Computer Science Student" << std::endl;
outputFile << "University of Programming" << std::endl;
// Close the file
outputFile.close();
std::cout << "Data written to file successfully!" << std::endl;
} else {
std::cout << "Unable to open file for writing." << std::endl;
}
return 0;
}
Compile the program:
g++ write_files.cpp -o write_files
Run the executable:
./write_files
Example output:
Data written to file successfully!
Verify the file contents:
cat student_data.txt
Example file contents:
John Doe
Alice Smith, 22 years old, GPA: 3.75
Computer Science Student
University of Programming
Key points about writing to files:
- Use
<<operator to write data to files std::endladds a new line- Can write strings, numbers, and variables
- Always check if file is open before writing
- Close the file after writing operations
You can think of writing to files like writing in a notebook. The ofstream is your pen, and the file is the page where you record information.
Read Data from Text Files
In this step, you'll learn how to read data from text files using the ifstream class in C++. Building on the previous steps, you'll explore different methods to read lines, words, and entire files.
Create a new C++ file called read_files.cpp:
touch ~/project/read_files.cpp
Add the following code to the read_files.cpp file:
#include <iostream>
#include <fstream>
#include <string>
int main() {
// Open the file created in the previous step
std::ifstream inputFile("student_data.txt");
// Check if the file is successfully opened
if (inputFile.is_open()) {
// Read entire line
std::string line;
std::cout << "Reading entire lines:" << std::endl;
while (std::getline(inputFile, line)) {
std::cout << line << std::endl;
}
// Reset file pointer to beginning
inputFile.clear();
inputFile.seekg(0, std::ios::beg);
// Read individual words
std::cout << "\nReading individual words:" << std::endl;
std::string word;
while (inputFile >> word) {
std::cout << word << " ";
}
std::cout << std::endl;
// Close the file
inputFile.close();
} else {
std::cout << "Unable to open file for reading." << std::endl;
}
return 0;
}
Compile the program:
g++ read_files.cpp -o read_files
Run the executable:
./read_files
Example output:
Reading entire lines:
John Doe
Alice Smith, 22 years old, GPA: 3.75
Computer Science Student
University of Programming
Reading individual words:
John Doe Alice Smith, 22 years old, GPA: 3.75 Computer Science Student University of Programming
Key points about reading files:
- Use
std::getline()to read entire lines - Use
>>operator to read individual words clear()andseekg()reset file pointer- Always check if file is open before reading
- Close the file after reading operations
You can think of reading files like extracting information from a book. The ifstream is your bookmark, helping you navigate through the text.
Check File Open Status
In this step, you'll learn how to check the status of file operations in C++ using various methods to verify if files are successfully opened and ready for reading or writing.
Create a new C++ file called file_status.cpp:
touch ~/project/file_status.cpp
Add the following code to the file_status.cpp file:
#include <iostream>
#include <fstream>
#include <string>
int main() {
// Attempt to open an existing file for reading
std::ifstream inputFile("student_data.txt");
// Method 1: Using is_open() to check file status
if (inputFile.is_open()) {
std::cout << "File opened successfully for reading." << std::endl;
// Perform reading operations
std::string line;
while (std::getline(inputFile, line)) {
std::cout << "Read line: " << line << std::endl;
}
inputFile.close();
} else {
std::cout << "Failed to open file for reading." << std::endl;
}
// Method 2: Using good() to check file state
std::ofstream outputFile("test_status.txt");
if (outputFile.good()) {
std::cout << "File opened successfully for writing." << std::endl;
outputFile << "Testing file status" << std::endl;
// Additional status checks
if (outputFile) {
std::cout << "File is in a good state for writing." << std::endl;
}
outputFile.close();
} else {
std::cout << "Failed to open file for writing." << std::endl;
}
// Method 3: Multiple status check methods
std::ifstream checkFile("non_existent_file.txt");
std::cout << "File status checks:" << std::endl;
std::cout << "is_open(): " << (checkFile.is_open() ? "True" : "False") << std::endl;
std::cout << "good(): " << (checkFile.good() ? "True" : "False") << std::endl;
std::cout << "fail(): " << (checkFile.fail() ? "True" : "False") << std::endl;
return 0;
}
Compile the program:
g++ file_status.cpp -o file_status
Run the executable:
./file_status
Example output:
File opened successfully for reading.
Read line: John Doe
Read line: Alice Smith, 22 years old, GPA: 3.75
Read line: Computer Science Student
Read line: University of Programming
File opened successfully for writing.
File is in a good state for writing.
File status checks:
is_open(): False
good(): False
fail(): True
Key points about file status checking:
is_open(): Checks if the file was successfully openedgood(): Checks if no errors have occurredfail(): Checks if an error has occurred- Always check file status before performing operations
- Different methods provide various ways to verify file state
You can think of file status checks like a safety inspection before a journey. These methods help ensure your file operations are safe and successful.
Handle File Read/Write Errors
In this step, you'll learn how to handle potential errors that can occur during file read and write operations in C++. Understanding error handling is crucial for creating robust file manipulation programs.
Create a new C++ file called file_error_handling.cpp:
touch ~/project/file_error_handling.cpp
Add the following code to the file_error_handling.cpp file:
#include <iostream>
#include <fstream>
#include <string>
#include <stdexcept>
void writeToFile(const std::string& filename) {
std::ofstream outputFile(filename);
// Check if file is open
if (!outputFile) {
// Throw an exception if file cannot be opened
throw std::runtime_error("Unable to open file for writing: " + filename);
}
try {
// Attempt to write data
outputFile << "Hello, Error Handling!" << std::endl;
outputFile << "This is a sample text." << std::endl;
// Simulate a write error (intentionally not recommended)
if (outputFile.bad()) {
throw std::runtime_error("Write operation failed");
}
}
catch (const std::exception& e) {
std::cerr << "Error during writing: " << e.what() << std::endl;
}
outputFile.close();
}
void readFromFile(const std::string& filename) {
std::ifstream inputFile(filename);
std::string line;
// Check if file is open
if (!inputFile) {
// Throw an exception if file cannot be opened
throw std::runtime_error("Unable to open file for reading: " + filename);
}
try {
// Read and print file contents
std::cout << "File contents:" << std::endl;
while (std::getline(inputFile, line)) {
std::cout << line << std::endl;
}
// Check for read errors
if (inputFile.bad()) {
throw std::runtime_error("Read operation encountered an error");
}
}
catch (const std::exception& e) {
std::cerr << "Error during reading: " << e.what() << std::endl;
}
inputFile.close();
}
int main() {
try {
// Write to a file
writeToFile("error_handling_example.txt");
// Read from the file
readFromFile("error_handling_example.txt");
// Attempt to read from a non-existent file
readFromFile("non_existent_file.txt");
}
catch (const std::exception& e) {
std::cerr << "Main error: " << e.what() << std::endl;
return 1;
}
return 0;
}
Compile the program:
g++ file_error_handling.cpp -o file_error_handling
Run the executable:
./file_error_handling
Example output:
File contents:
Hello, Error Handling!
This is a sample text.
Error during reading: Unable to open file for reading: non_existent_file.txt
Key points about file error handling:
- Use
try-catchblocks to handle potential exceptions - Check file stream state before and after operations
- Use
std::runtime_errorfor throwing meaningful error messages - Handle different types of file-related errors
- Provide informative error messages
You can think of error handling like a safety net. It catches potential problems and prevents your program from crashing unexpectedly.
Work with Binary Files Using fstream
In this step, you'll learn how to work with binary files using the fstream class in C++. Binary files store data in its raw binary format, which is different from text files and useful for storing structured data efficiently.
Create a new C++ file called binary_files.cpp:
touch ~/project/binary_files.cpp
Add the following code to the binary_files.cpp file:
#include <iostream>
#include <fstream>
#include <string>
// Simple struct to demonstrate binary file writing
struct Student {
int id;
char name[50];
double gpa;
};
void writeBinaryFile() {
std::fstream binaryFile("students.bin", std::ios::out | std::ios::binary);
if (!binaryFile) {
std::cerr << "Error opening file for writing!" << std::endl;
return;
}
// Create some student records
Student students[3] = {
{1, "John Doe", 3.5},
{2, "Alice Smith", 3.8},
{3, "Bob Johnson", 3.2}
};
// Write entire struct to binary file
binaryFile.write(reinterpret_cast<char*>(students), sizeof(students));
binaryFile.close();
std::cout << "Binary file written successfully!" << std::endl;
}
void readBinaryFile() {
std::fstream binaryFile("students.bin", std::ios::in | std::ios::binary);
if (!binaryFile) {
std::cerr << "Error opening file for reading!" << std::endl;
return;
}
Student students[3];
// Read entire struct from binary file
binaryFile.read(reinterpret_cast<char*>(students), sizeof(students));
std::cout << "Student Records:" << std::endl;
for (int i = 0; i < 3; ++i) {
std::cout << "ID: " << students[i].id
<< ", Name: " << students[i].name
<< ", GPA: " << students[i].gpa << std::endl;
}
binaryFile.close();
}
int main() {
// Write binary file
writeBinaryFile();
// Read binary file
readBinaryFile();
return 0;
}
Compile the program:
g++ binary_files.cpp -o binary_files
Run the executable:
./binary_files
Example output:
Binary file written successfully!
Student Records:
ID: 1, Name: John Doe, GPA: 3.5
ID: 2, Name: Alice Smith, GPA: 3.8
ID: 3, Name: Bob Johnson, GPA: 3.2
Key points about binary files:
- Use
std::ios::binaryflag for binary mode write()andread()methods for binary datareinterpret_castused to convert between types- Useful for storing structured data efficiently
- Preserves exact binary representation of data
You can think of binary files like a precise blueprint. They store data exactly as it exists in memory, without any text conversion.
Position File Pointer with seekg/seekp
In this step, you'll learn how to manipulate file pointers using seekg() for reading and seekp() for writing in C++. These methods allow you to navigate and modify specific positions within a file.
Create a new C++ file called file_pointer.cpp:
touch ~/project/file_pointer.cpp
Add the following code to the file_pointer.cpp file:
#include <iostream>
#include <fstream>
#include <string>
void createSampleFile() {
std::ofstream file("numbers.txt");
for (int i = 1; i <= 10; ++i) {
file << i << " ";
}
file.close();
}
void demonstrateSeekOperations() {
// Open file in read and write mode
std::fstream file("numbers.txt", std::ios::in | std::ios::out);
if (!file) {
std::cerr << "Error opening file!" << std::endl;
return;
}
// Reading from different positions
std::cout << "Reading operations:" << std::endl;
// Move to the 5th byte (character position)
file.seekg(5);
int value;
file >> value;
std::cout << "Value at 5th byte: " << value << std::endl;
// Move to the beginning of the file
file.seekg(0);
file >> value;
std::cout << "First value: " << value << std::endl;
// Writing at specific positions
std::cout << "\nWriting operations:" << std::endl;
// Move to a specific position and write
file.seekp(0);
file << "100 ";
// Reset file pointer and read to verify
file.seekg(0);
file >> value;
std::cout << "Modified first value: " << value << std::endl;
file.close();
}
int main() {
// Create a sample file with numbers
createSampleFile();
// Demonstrate seek operations
demonstrateSeekOperations();
return 0;
}
Compile the program:
g++ file_pointer.cpp -o file_pointer
Run the executable:
./file_pointer
Example output:
Reading operations:
Value at 5th byte: 4
First value: 1
Writing operations:
Modified first value: 100
Key points about file pointers:
seekg(): Moves read pointer (get pointer)seekp(): Moves write pointer (put pointer)- First argument is byte position
- Useful for random access in files
- Can navigate to specific locations
You can think of file pointers like a cursor in a text editor. seekg() and seekp() help you move this cursor precisely where you want.
Close Files and Release Resources
In this step, you'll learn about the importance of properly closing files and managing resources in C++ to prevent memory leaks and ensure efficient file handling. You'll explore different methods of closing files and using RAII (Resource Acquisition Is Initialization) principles.
Create a new C++ file called file_resources.cpp:
touch ~/project/file_resources.cpp
Add the following code to the file_resources.cpp file:
#include <iostream>
#include <fstream>
#include <string>
#include <memory>
// Manual file closing
void manualFileHandling() {
std::ofstream outputFile("manual_file.txt");
if (outputFile.is_open()) {
outputFile << "Manually managed file resource" << std::endl;
// Explicitly close the file
outputFile.close();
std::cout << "File closed manually." << std::endl;
}
}
// RAII-based file handling using unique_ptr
void raii_fileHandling() {
try {
// Using unique_ptr to manage file resource
std::unique_ptr<std::ofstream> file(new std::ofstream("raii_file.txt"));
if (file && file->is_open()) {
*file << "RAII-managed file resource" << std::endl;
std::cout << "RAII file handling successful." << std::endl;
}
// File automatically closed when unique_ptr goes out of scope
}
catch (const std::exception& e) {
std::cerr << "Error in RAII file handling: " << e.what() << std::endl;
}
}
// Scope-based file handling
void scopeBasedFileHandling() {
{
// File will be automatically closed when it goes out of scope
std::ofstream scopedFile("scoped_file.txt");
if (scopedFile.is_open()) {
scopedFile << "Scope-based file resource management" << std::endl;
std::cout << "Scoped file handling successful." << std::endl;
}
} // File automatically closed here
}
int main() {
// Demonstrate different file resource management techniques
manualFileHandling();
raii_fileHandling();
scopeBasedFileHandling();
return 0;
}
Compile the program:
g++ file_resources.cpp -o file_resources
Run the executable:
./file_resources
Example output:
File closed manually.
RAII file handling successful.
Scoped file handling successful.
Key points about closing files and managing resources:
- Always close files after use
- Use
close()method for manual closing - Leverage RAII principles
- Use scope-based resource management
- Prevent resource leaks
- Handle exceptions during file operations
You can think of file resources like borrowing a book from a library. Always return the book (close the file) when you're done to keep the library (system resources) organized.
Summary
In this lab, you learned how to open files in C++ using the ofstream and ifstream classes from the standard library. You explored the process of checking the file open status, writing text data to files, and reading data from text files. Additionally, you gained an understanding of handling file read/write errors, working with binary files using fstream, positioning the file pointer with seekg/seekp, and properly closing files and releasing resources. These fundamental file operations are essential for managing data storage and retrieval in C++ applications.



