What is File handling in C++?
- File handling in C++ refers to the ability of a C++ program to read data and write data to files.
- File handling allows programs to interact with external files, such as text files, binary files, and more.
C++ Streams
In C++, streams are used for input and output operations. There are two basic stream classes:
- istream: Used for input (e.g., cin for keyboard input).
- ostream: Used for output (e.g., cout for console output).
C++ Predefined Streams
C++ provides three predefined streams:
- cin: Standard input stream, used for reading from the keyboard.
- cout: Standard output stream, used for writing to the console.
- cerr: Standard error stream, used for writing error messages to the console.
I/O Operations
I/O operations involve reading and writing data. For example:
1#include <iostream>
2
3int main() {
4 int num;
5 std::cout << "Enter a number: ";
6 std::cin >> num;
7 std::cout << "You entered: " << num << std::endl;
8 return 0;
9}
In this code, we read an integer from the user using cin and output the result using cout.
Unformatted Console I/O Operations
Unformatted I/O includes functions like get() and put() for character-based input and output.
1#include <iostream>
2
3int main() {
4 char ch;
5 std::cout << "Enter a character: ";
6 ch = std::cin.get();
7 std::cout.put(ch);
8 return 0;
9}
Manipulators
- Manipulators are functions or objects that allow you to control the formatting of data when it's being displayed.
- For example, std::setw() sets the width of the output field, ensuring that the output is neatly aligned.
1#include <iostream>
2#include <iomanip>
3using namespace std;
4
5int main()
6{
7 int num = 42;
8 cout << setw(10) << num << endl;
9 return 0;
10}
In this code, setw(10) sets the width of the output to 10 characters, ensuring the number is right-aligned.
File Modes in C++
Input Mode (ios::in)
- When you open a file with ios::in mode, you are specifying that you intend to read data from the file.
- If the file does not exist or cannot be opened for reading, an error will occur.
Syntax:
1ifstream file("filename", ios::in);
Input Mode in C++ Example
1#include <iostream>
2#include <fstream>
3using namespace std;
4
5int main() {
6 ifstream inputFile("example.txt", ios::in);
7
8 if (!inputFile) {
9 cerr << "Failed to open the file for reading." << endl;
10 return 1;
11 }
12
13 string line;
14 while (getline(inputFile, line)) {
15 cout << line << endl;
16 }
17
18 inputFile.close();
19
20 return 0;
21}
Output Mode (ios::out)
- This mode is used to open a file for writing.
- If the file exists, its content will be truncated; if it doesn't exist, a new file will be created.
- Syntax:
1ofstream file("filename", ios::out);
Output Mode in C++
1#include <iostream>
2#include <fstream>
3using namespace std;
4
5int main() {
6 ofstream outputFile("output.txt", ios::out);
7
8 if (!outputFile) {
9 cerr << "Failed to open the file for writing." << endl;
10 return 1;
11 }
12
13 outputFile << "Hello, World!" << endl;
14 outputFile.close();
15
16 return 0;
17}
Append Mode (
This mode is used to open a file for writing, appending data to the end if it exists, or creating a new file if it doesn't.
Syntax:
1ofstream file("filename", ios::app);
Append Mode in C++
1#include <iostream>
2#include <fstream>
3using namespace std;
4
5int main() {
6 ofstream logFile("log.txt", ios::app);
7
8 if (!logFile) {
9 cerr << "Failed to open the file for appending." << endl;
10 return 1;
11 }
12
13 logFile << "Log entry 1" << endl;
14 logFile << "Log entry 2" << endl;
15 logFile.close();
16
17 return 0;
18}
Binary Mode (
This mode is used when working with binary files.
Syntax:
1ifstream or ofstream file("filename", ios::binary);
Binary Mode in C++
1#include <iostream>
2#include <fstream>
3using namespace std;
4
5int main() {
6 ifstream binaryInput("data.bin", ios::binary);
7
8 if (!binaryInput) {
9 cerr << "Failed to open the binary file." << endl;
10 return 1;
11 }
12
13 int data;
14 while (binaryInput.read(reinterpret_cast<char*>(&data), sizeof(data))) {
15 cout << "Read data: " << data << endl;
16 }
17
18 binaryInput.close();
19
20 return 0;
21}
Opening and Closing a File in C++
- In C++, you can work with files by using ifstream (for reading) and ofstream (for writing) classes.
- To open a file, you typically provide its name and specify the mode (ios::in for input, ios::out for output).
1#include <iostream>
2#include <fstream>
3using namespace std;
4
5int main()
6{
7 ofstream outFile("example.txt"); // Opening a file for writing
8 // Write data to the file
9 outFile << "Hello, file!" << endl;
10 outFile.close(); // Close the file when done
11 return 0;
12}
Opening and closing files is crucial to ensure that data is properly saved and resources are released.
Error Handling during File Operations in C++
- When working with files, it's essential to check whether file operations were successful.
- For example, when opening a file, you should verify if it opened successfully using the is_open() function.
Sequential Access to File
- Sequential access to a file means reading or writing data in the order it appears in the file, from the beginning to the end.
- Here's an example of reading and writing sequentially to a file:
1#include <iostream>
2#include <fstream>
3using namespace std;
4
5int main() {
6 // Writing data sequentially to a file
7 ofstream outputFile("sequential.txt");
8
9 if (!outputFile) {
10 cerr << "Failed to open the file for writing." << endl;
11 return 1;
12 }
13
14 outputFile << "Line 1" << endl;
15 outputFile << "Line 2" << endl;
16 outputFile << "Line 3" << endl;
17
18 outputFile.close();
19
20 // Reading data sequentially from the same file
21 ifstream inputFile("sequential.txt");
22
23 if (!inputFile) {
24 cerr << "Failed to open the file for reading." << endl;
25 return 1;
26 }
27
28 string line;
29 while (getline(inputFile, line)) {
30 cout << line << endl;
31 }
32
33 inputFile.close();
34
35 return 0;
36}
In this code, we first write three lines of text sequentially to a file and then read them back sequentially.
Random Input and Output Operations
- Random input and output operations involve moving the file pointer to a specific location in the file and reading or writing data from that point.
- Here's an example of random access:
1#include <iostream>
2#include <fstream>
3using namespace std;
4
5int main() {
6 fstream file("random_access.txt", ios::in | ios::out);
7
8 if (!file) {
9 cerr << "Failed to open the file." << endl;
10 return 1;
11 }
12
13 // Writing data at a specific position (e.g., position 10)
14 file.seekp(10);
15 file << "Hello";
16
17 // Reading data from a specific position (e.g., position 5)
18 file.seekg(5);
19 string data;
20 file >> data;
21
22 cout << "Data at position 5: " << data << endl;
23
24 file.close();
25
26 return 0;
27}
- In this code, we open a file for both reading and writing. We use seekp to set the file pointer to position 10 and write "Hello" there.
- Then, we use seekg to move the file pointer to position 5 and read data from that position.
Persistent Objects
Persistent objects are objects that can be saved to a file and loaded back later. Here's a simple example using serialization:
1#include <iostream>
2#include <fstream>
3#include <string>
4using namespace std;
5
6class Person {
7public:
8 string name;
9 int age;
10
11 void Save(ofstream& file) {
12 file << name << endl;
13 file << age << endl;
14 }
15
16 void Load(ifstream& file) {
17 getline(file, name);
18 file >> age;
19 file.ignore(); // Ignore the newline character
20 }
21};
22
23int main() {
24 // Saving a Person object to a file
25 Person person;
26 person.name = "Alice";
27 person.age = 30;
28
29 ofstream outputFile("person.txt");
30
31 if (!outputFile) {
32 cerr << "Failed to open the file for writing." << endl;
33 return 1;
34 }
35
36 person.Save(outputFile);
37 outputFile.close();
38
39 // Loading and displaying the saved Person object
40 ifstream inputFile("person.txt");
41
42 if (!inputFile) {
43 cerr << "Failed to open the file for reading." << endl;
44 return 1;
45 }
46
47 Person loadedPerson;
48 loadedPerson.Load(inputFile);
49
50 cout << "Loaded Person: " << loadedPerson.name << ", Age: " << loadedPerson.age << endl;
51
52 inputFile.close();
53
54 return 0;
55}
- In this code, we have a Person class with Save and Load methods to serialize and deserialize the object's data to/from a file.
- We save a Person object to a file, and then we load and display the saved object.
Command Line Arguments
- Command line arguments are values passed to a program when it is executed from the command line.
- Here's a simple example of how to access and use command line arguments:
1#include <iostream>
2using namespace std;
3
4int main(int argc, char* argv[]) {
5 cout << "Number of command line arguments: " << argc << endl;
6
7 cout << "Command line arguments:" << endl;
8 for (int i = 0; i < argc; ++i) {
9 cout << "Argument " << i << ": " << argv[i] << endl;
10 }
11
12 return 0;
13}
- In this code, argc represents the number of command line arguments, and argv is an array of C-style strings (char arrays) containing the actual argument values.
- We print the number of arguments and then loop through and print each argument's value.
Conclusion
File handling in C++ is a crucial aspect of programming, allowing us to interact with external files for reading, writing, and manipulating data.