CSC10012
FILE HANDLING IN C++
FIT-HCMUS
Contents
1 Standard file stream class in C++ 2
1.1 std::fstream . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.2 std::ifstream . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.3 std::ofstream . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
2 Essential text file handling functions 3
2.1 open() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
2.2 close() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
2.3 is_open() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
2.4 eof() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
2.5 getline() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
2.6 Extraction operator (») . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.7 Insertion Operator («) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
3 Essential binary file handling functions 6
3.1 open() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
3.2 close() and is_open() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
3.3 read() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
3.4 tellg() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
3.5 seekg() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
3.6 write() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
3.7 tellp() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
3.8 seekp() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
4 Practical examples 8
4.1 Text file handling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
4.2 Binary file handling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
5 Some notes 12
1
Fundamentals of Programming | CSC10012 Department of Knowledge Engineering
1 Standard file stream class in C++
1.1 std::fstream
• Input/output stream class to operate on files, including reading, writing, and appending.
• Example usage:
#include <fstream> // std::fstream
int main () {
std::fstream fs;
// Open then "test.txt" file to read, write, or append content
fs.open("test.txt", std::fstream::in | std::fstream::out | std::fstream::app);
// Insert the text "Hello World" into the file
fs << "Hello World";
// Close the file
fs.close();
return 0;
}
• Learn more at: std::fstream C++
1.2 std::ifstream
• Stream class to read from files.
• Example usage:
#include <iostream> // std::cout
#include <fstream> // std::ifstream
#include <string> // std::getline
int main() {
std::ifstream fin;
// Open the "test.txt" file to read content
// File only contains the line "Hello World"
fin.open("test.txt");
std::string s = "";
std::getline(fin, s); // Read the line "Hello World" from the file into the string s
// Close the file
fin.close();
Page 2 / 12
Fundamentals of Programming | CSC10012 Department of Knowledge Engineering
std::cout << s; // Print the line "Hello World" to the Console
return 0;
}
• Learn more at: std::ifstream C++
1.3 std::ofstream
• Stream class to write on files.
• Example usage:
#include <fstream> // std::ofstream
int main () {
std::ofstream fout;
// Open the "test.txt" file to write or append
fout.open("test.txt", std::ofstream::out | std::ofstream::app);
// Inset the text "Hello World" into the file
fout << "Hello World";
// close the file
fout.close();
return 0;
}
• Learn more at: std::ofstream C++
2 Essential text file handling functions
2.1 open()
• Opens a file.
• Different stream classes have different ways of calling functions, primarily in the second parameter. Refer to
section 1 for more details.
2.2 close()
• Closes a file.
• Example:
f.close();
Page 3 / 12
Fundamentals of Programming | CSC10012 Department of Knowledge Engineering
2.3 is_open()
• Checks if a file is open.
• Returns true if a file is opened sucessfully, false otherwise.
• Example:
if (!fin.is_open()) {
std::cout << "Error opening file!";
return 0;
}
2.4 eof()
• Checks if eofbit is set.
• Returns true if the stream’s eofbit error state flag is set (which signals that the End-of-File has been reached
by the last input operation), false otherwise.
• Example:
while (!fin.eof()) { // Loop until the end-of-file indicator is reached
std::getline(fin, s);
}
2.5 getline()
• Reads characters from an input stream and places them into a string (std::string).
• To use this function, you must include the <string> header file.
• The following are ways to use the function, assuming the data line to be read is "Name;Age;BirthYear\n":
1. Read an entire line from the file.
– Example: std::getline(fin, s);
– After executing this command, the entire data of the line in the file will be read into s, and the
newline character (\n) will be removed.
– Result: s = "Name;Age;BirthYear".
2. Read until a delimiter is encountered.
– Example: std::getline(fin, s, ’;’);
– After executing this command, s will receive information from the beginning of the line until the
delimiter ; is met.
– Result: s = "Name".
Page 4 / 12
Fundamentals of Programming | CSC10012 Department of Knowledge Engineering
2.6 Extraction operator (»)
• Extracts characters from an input stream (in this scenario, it is a file stream).
• This operator is used similarly to std::cin >>.
• The extraction stops if any of the following conditions is met:
– A whitespace character (a space ’ ’, tab ’\t’, newline ’\n’...) is found. The whitespace character is
not extracted.
– End of file occurs in the input sequence (this also sets eofbit).
• Example: Reading a 1D array from a file "in.txt" with the following content:
5
1 3 5 7 -1
You only need to use the extraction operator without using std::getline.
...
int arr[100];
int n = 0;
std::ifstream fin("in.txt"); // Open the file to read content
fin >> n; // Read the number of elements of the array
for (int i = 0; i < n; i++)
fin >> arr[i]; // Read each element
fin.close();
...
• If the file content does not include the number of elements but only the array data (e.g., 1 3 5 7 -1), we
can use a while loop to read the file content.
...
int arr[100];
int n = 0; // In this case, n must be initialized to 0.
std::ifstream fin("in.txt");
while (fin >> arr[n])
n++;
fin.close();
...
Note: Avoid combining n++ with ifs >> arr[n]. If the file content ends with a whitespace or newline
character, the combined operation would increment n prematurely, leading to the last element being garbage.
Page 5 / 12
Fundamentals of Programming | CSC10012 Department of Knowledge Engineering
2.7 Insertion Operator («)
• Inserts values (e.g. single character, character sequence...) into an output stream (in this scenario, it is a file
stream).
• This operator is used similarly to std::cout <<.
• Example: Square each element of the array read above and write the results to the file "out.txt").
...
std::ofstream fout("out.txt"); // Open the file to write
fout << n; // Write the number of elements of the array
for (int i = 0; i < n; i++)
fout << arr[i] * arr[i] << " "; // Write square of each element
fout.close();
...
3 Essential binary file handling functions
3.1 open()
• Opens a file and associates it with the stream.
• Example:
std::ifstream fin;
fin.open("data.bin", std::ifstream::binary);
3.2 close() and is_open()
• These two functions are used in the same way for text file handling.
3.3 read()
• Reads/extracts blocks of characters.
• Example: Given a binary file named "data.bin", read the first 4 bytes as the array size. Then, allocate
memory and read the remaining bytes into the array.
...
std::ifstream fin;
fin.open("data.bin", std::ifstream::binary);
int n = 0;
fin.read((char*)&n, (int)sizeof(int));
int* arr = new int [n];
Page 6 / 12
Fundamentals of Programming | CSC10012 Department of Knowledge Engineering
fin.read((char*)arr, n*sizeof(int));
fin.close();
...
3.4 tellg()
• Returns the input position indicator.
• Example: Use the file above.
...
std::ifstream fin;
fin.open("data.bin", std::ifstream::binary);
int n = 0;
fin.read((char*)&n, (int)sizeof(int));
std::cout << fin.tellg();
// The console output is 4
...
3.5 seekg()
• Sets the input position indicator.
• Example: Consider a binary file named "data.bin" that solely consists of an integer array. The number of
elements within this array is not explicitly provided.
...
std::ifstream fin;
fin.open("data.bin", std::ifstream::binary);
int n = 0;
fin.seekg(0, std::ifstream::end); // Set the position indicator to the end of file
n = fin.tellg() / sizeof(int); // n now stores the total number of elements in the array
fin.seekg(0, std::ifstream::beg); // Set the position indicator to the beginning of file
...
3.6 write()
• Writes/inserts blocks of characters.
• Example:
...
int arr[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
std::ofstream fout("data.bin", std::ofstream::binary);
Page 7 / 12
Fundamentals of Programming | CSC10012 Department of Knowledge Engineering
fout.write((char*)arr, (int)sizeof(arr));
fout.close();
...
3.7 tellp()
• Returns the output position indicator.
• Example:
...
int arr[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
std::ofstream fout("data.bin", std::ofstream::binary);
fout.write((char*)arr, (int)sizeof(arr));
std::cout << fout.tellp();
// The console output is 40
fout.close();
...
3.8 seekp()
• Sets the output position indicator.
• Example:
...
int arr[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
std::ofstream fout("data.bin", std::ofstream::binary);
fout.write((char*)arr, (int)sizeof(arr));
// Modify the final element of the array to -1
fout.seekp(-(int)sizeof(int), ofstream::end);
int value = -1;
fout.write((char*)&value, (int)sizeof(int));
fout.close();
...
4 Practical examples
4.1 Text file handling
Problem: Read the data from the file named "data.txt" and store it. The file contains the following information:
Page 8 / 12
Fundamentals of Programming | CSC10012 Department of Knowledge Engineering
Name;Math;Literature
Hoa;9;7
Loan;8;8
Hung;7;8
Thanh;10;9.5
Next, save the student’s name and the total score of their two subjects to a file named "result.txt". The data
should be formatted as follows:
Name;TotalScore
Hoa;16
Loan;16
Hung;15
Thanh;19.5
Solution:
#include <iostream>
#include <fstream> // std::ifstream, std::ofstream
#include <string> // std::getline, std::stof
#include <vector>
using namespace std;
struct Student {
string name;
float math, literature;
};
int main() {
// PART 1: READ DATA FROM FILE
// Open the "data.txt" file to read content
ifstream fin;
fin.open("data.txt");
// Quit if file open fails
if (!fin.is_open()) {
cout << "Error opening file!";
return 0;
}
// Ignore the line "Name;Math;Literature"
string ignore_line = "";
getline(fin, ignore_line);
// Declare variables
vector<Student> list_student;
Student temp_student;
string name = "";
Page 9 / 12
Fundamentals of Programming | CSC10012 Department of Knowledge Engineering
string math = "";
string literature = "";
// Keep reading until the end of the file is reached or a read operation fails
while (getline(fin, name, ’;’)) {
// The name content is read first to avoid duplicate information
// when there is an empty line at the end of the file
// Read others from the file into temporary variables
getline(fin, math, ’;’);
getline(fin, literature, ’\n’);
// Assign data from the temporary variables to the Student struct
temp_student.name = name;
temp_student.math = stof(math); // Convert Math score from string to float
temp_student.literature = stof(literature); // Convert Literature score from string to float
// Push the read student data into a vector of students
list_student.push_back(temp_student);
}
// Close the file
fin.close();
//------------------------------------------------------------
// PART 2: SAVE DATA TO FILE
// Open file to save data
ofstream fout;
fout.open("result.txt");
// Quit if file open fails
if (!fout.is_open()) {
cout << "Error opening file!";
return 0;
}
// Save data to the file
fout << "Name;TotalScore\n";
for (int i = 0; i < list_student.size(); i++) {
fout << list_student[i].name << ";";
fout << list_student[i].math + list_student[i].literature << "\n";
}
// Close the file
fout.close();
return 0;
}
Page 10 / 12
Fundamentals of Programming | CSC10012 Department of Knowledge Engineering
4.2 Binary file handling
Problem: Read student records from the binary file "data.bin". Each 28-byte record contains a fixed-width field
structure: 9-byte ID, 9-byte last name, 10-byte first name. Extract records with IDs matching the 2024 class prefix
"2412" and save them to a binary file named "result.bin".
Solution:
#include <iostream>
#include <fstream>
#include <cstring>
using namespace std;
struct Student {
char id[9];
char lastName[9];
char firstName[10];
};
int main() {
// PART 1: READ DATA FROM FILE
ifstream fin("data.bin", ifstream::binary);
// Find the number of student records
fin.seekg(0, ifstream::end);
int n = fin.tellg() / 28;
fin.seekg(0, ifstream::beg);
// Dynamically allocate an array for storing student records
Student* list = new Student[n];
// Read n student records
for (int i = 0; i < n; i++) {
fin.read((char*)&list[i].id, 9);
fin.read((char*)&list[i].lastName, 9);
fin.read((char*)&list[i].firstName, 10);
}
// We can use fin.read((char*)list, n*sizeof(Student)); in this case.
// But it’s not guaranteed for other data structures due to potential alignment issues.
// Close the file
fin.close();
//------------------------------------------------------------
// PART 2: SAVE DATA TO FILE
ofstream fout("result.bin", ofstream::binary);
Page 11 / 12
Fundamentals of Programming | CSC10012 Department of Knowledge Engineering
// Extract and save records to file
for (int i = 0; i < n; i++)
if (strncmp(list[i].id, "2412", 4) == 0) {
fout.write((char*)&list[i].id, 9);
fout.write((char*)&list[i].lastName, 9);
fout.write((char*)&list[i].firstName, 10);
// Or fout.write((char*)&list[i], (int)sizeof(Student));
}
// Close the file
fout.close();
// Deallocate the dynamically allocated array
delete[] list;
return 0;
}
5 Some notes
1. When opening a file, it is MANDATORY to close the file.
2. When opening a file for writing (using std::ofstream::out), there are two possible scenarios:
(a) The file does not exist: A new file is created, and the new content is written to it.
(b) The file already exists: The existing content in the file is completely overwritten, and the new content is
written to it.
3. To append data to an existing file, use std::ofstream::app.
4. Position the file pointer to the beginning (seekg(0, ifstream::beg)) or end (seekg(0, ifstream::end)).
5. Seek within a binary file using positive offsets from the beginning or negative offsets from the end.
THE END
Page 12 / 12