What is File handling in C++?

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.