OOP Unit 4 Notes
OOP Unit 4 Notes
Unit – IV
Files and Streams
1. Data Hierarchy
When a computer is powered off, the contents of its main memory are lost. Therefore, to
preserve data, we store it on disks or similar permanent storage devices. Data in computer
systems follows a structured hierarchy to optimize storage, access, and processing.
A file is a sequence of bytes stored in secondary (permanent) storage. Each file has a unique
name for identification and follows a specific data format. The essential features of a file
include:
Executable: If the file is of an executable type, it can be loaded and run by the system.
To execute a file, it must be transferred to the main memory (RAM), where it is then referred
to as a program. This transfer process is handled by the I/O (Input/Output) system,
facilitating the movement of data between primary and secondary storage.
2|Page
1. Secondary Storage (File): The initial location where data and programs are stored
permanently.
2. Main Memory (Program): Temporary storage for active programs, allowing CPU
access for execution.
For program execution, files must be loaded from secondary storage to main memory by the
system’s I/O processes.
Data Hierarchy
3. Fields: A field is a combination of one or more related characters (or bytes) and is the
smallest unit of data a user accesses. A field name uniquely identifies each field. The
field size defines the maximum number of characters a field can contain.
4. Records: A record is a group of related fields. For example, a student record includes a
set of fields about one student.
3|Page
5. Files: A data file is a collection of related records stored on a storage medium such as
a hard disk or an optical disc.
In C++, input and output operations are handled as sequences of bytes, commonly referred to
as streams. These streams provide a structured way to perform input and output (I/O) by
directing data flow between memory and devices. C++ includes libraries that offer a range of
tools for handling I/O tasks efficiently.
Types of Streams
1. Input Stream: When data flows from a device (e.g., keyboard) into main memory, this
is referred to as an input stream.
2. Output Stream: When data flows in the opposite direction, from main memory to a
device (e.g., display screen), it’s termed an output stream.
1. Text Stream:
o Some characters, such as newline (\n) or tab (\t), are stored with system-
specific encoding, so the representation of the data may not directly map one-
to-one between the device file and the stream.
2. Binary Stream:
C++ provides several essential header files for input and output operations:
1. <iostream>:
o The <iostream> library includes standard input and output stream objects like
cin, cout, and cerr.
o cin (console input) is used for accepting user input, and cout (console output)
is used for displaying output on the screen.
2. <iomanip>:
o It includes utilities like setw for setting the width of the output and
setprecision for defining the precision of floating-point numbers.
In C++, input and output operations can be categorized into two types: formatted and
unformatted. These categories determine how data is processed when reading from or writing
to streams. Here’s a breakdown of both types along with examples.
1. Formatted Input/Output
Formatted Input/Output functions are used to read and write data in a way that respects the
specified formatting. These functions include cout and cin, which handle data according to
its type and format.
Examples:
5|Page
#include <iostream>
#include <iomanip> // for setw and setprecision
using namespace std;
int main() {
double pi = 3.14159;
cout << fixed << setprecision(2); // Set fixed decimal format with
2 decimal places
cout << "Formatted output of pi: " << pi << endl;
cout << setw(10) << "Number" << endl; // Set width for output
cout << setw(10) << 42 << endl; // Right align output in a width
of 10
cout << setw(10) << 100 << endl;
return 0;
}
2. Unformatted Input/Output
Unformatted Input/Output functions are used to read and write data in a raw format, without
any formatting. This type of input/output is faster but does not handle type conversions or
formatting.
Examples:
Unformatted Output: Using write() to write raw data to a file or output stream.
#include <iostream>
#include <fstream>
using namespace std;
int main() {
char data[] = "Hello, World!";
6|Page
return 0;
}
3. <fstream>:
o It includes classes like ifstream (input file stream) and ofstream (output
file stream) for reading from and writing to files.
To use cin and cout for basic input and output, the <iostream> header file must be
included in your program.
The standard output stream is typically linked to the display screen. In C++, cout (character
output) is an instance of the ostream class and is used to print data to the screen.
The insertion operator (<<) is used with cout to send data to the output stream.
The standard input stream generally refers to the keyboard. In C++, cin (character input)
is an instance of the istream class and is used to receive input from the user.
The extraction operator (>>) is used with cin to retrieve data from the input stream.
#include <iostream>
using namespace std;
int main() {
int age;
cout << "Enter your age: "; // Prompting user
7|Page
o It outputs error messages directly to the display without using any buffering,
making it ideal for immediate error display.
o Unlike cerr, clog uses a buffer. The error message is stored temporarily until
the buffer is full, providing a delayed output.
#include <iostream>
using namespace std;
int main() {
int divisor;
cout << "Enter a divisor: ";
cin >> divisor;
if (divisor == 0) {
cerr << "Error: Division by zero is not allowed!" << endl; //
Unbuffered error output
clog << "Log: Division attempt with zero as divisor." << endl;
// Buffered error output
8|Page
} else {
cout << "Result: " << (10 / divisor) << endl;
}
return 0;
}
In this example:
cerr displays an error message immediately if the user tries to divide by zero.
clog stores a log message in a buffer and outputs it when the buffer fills, allowing for
efficient error logging over time.
In simple terms, a stream in C++ is a “file in use.” While a file is static data stored on a device,
a stream represents this file as it is opened and used in memory for operations such as reading,
writing, or even sending data over a network. In essence, the stream is an interface between the
user and the actual device file, whether that file resides on a disk, tape, or flash drive.
Regardless of the source, streams in C++ provide the same set of operations to handle file data
consistently.
C++ offers a hierarchy of built-in classes in the <iostream> and <fstream> libraries, which
simplify file and stream operations. These classes provide functions to open files, manipulate
data, and save and close files after processing.
The stream classes are organized hierarchically, with ios as the top-level class that provides
the foundation for both input and output operations. Here is a breakdown of key stream classes
and their roles:
ios class: This is the base class for handling both input and output operations. It is the
foundation of the stream hierarchy.
istream class: Inherits from ios and provides functions for handling input, including
character and string input, with functions like get, getline, read, ignore, and
putback.
9|Page
ostream class: Inherits from ios and handles output operations, providing functions
for outputting characters, strings, and objects using functions such as write and put.
iostream class: Inherits from both istream and ostream (virtually), allowing it to
handle both input and output in a single object.
#include <iostream>
using namespace std;
int main() {
char x;
return 0;
10 | P a g e
}
In this example:
1. ios Class: Supplies essential input and output functions to all derived stream classes.
2. istream Class: Manages input operations. It includes functions such as get, getline,
read, ignore, and putback.
#include <iostream>
using namespace std;
int main() {
char x;
cin.get(x); // Reads a single character
cout << x;
return 0;
}
3. ostream Class: Manages output operations. It includes functions such as write and put.
#include <iostream>
using namespace std;
int main() {
char x;
cin.get(x); // Reads a single character
cout.put(x); // Outputs the character
return 0;
}
4. iostream Class: Manages both input and output operations. It combines functionalities
from both istream and ostream.
11 | P a g e
#include <iostream>
using namespace std;
int main() {
cout.write("ObjectOriented", 5); // Displays "Objec"
return 0;
}
Specialized Stream Classes for Assignment
#include <iostream>
using namespace std;
class Demo {
public:
int dx, dy;
int main() {
Demo d;
cout << "Enter two numbers dx and dy:\n";
d >> cin; // Equivalent to operator>>(d, cin);
cout << "dx = " << d.dx << "\tdy = " << d.dy;
return 0;
12 | P a g e
}
ostream_withassign: This variant of ostream allows object reassignment, so
predefined objects like cout, cerr, and clog can be redirected at runtime.
#include <iostream>
using namespace std;
class Demo {
public:
int dx, dy;
int main() {
Demo d;
d << cout; // Equivalent to operator<<(d, cout);
return 0;
}
In this example, operator << is overloaded to print the object’s data members dx and dy via
cout.
Summary
iostream: Manages both input and output, inheriting features of istream and
ostream.
File: A file is a collection of related data stored on a device, such as a disk, flash drive, or CD.
Every file is associated with a unique file name composed of a name and an extension (e.g.,
data.txt).
To interact with a file (read, write, or modify), we must first open it. C++ provides a set of
classes for handling files through streams, which offer standardized methods for file access.
To open a file, we create an object of the relevant stream class and use the open() function.
FileName: A string specifying the full file path. If the file is in the same directory as
the program, only the file name is needed.
Mode: An integer value that specifies the file access mode, such as read or write. These
modes are predefined constants in the ios class. The compiler assumes the mode based
on the stream class used.
Example:
#include <fstream>
using namespace std;
int main() {
ifstream fin; // Create ifstream object for input
fin.open("mydata.txt"); // Open file in input mode by default
fin.close(); // Close the file after operations
return 0;
}
14 | P a g e
The close() function saves the data to the file and closes it properly.
1. fstreambase: Base class for file streams. Contains the common open() and
close() functions and serves as a foundation for ifstream, ofstream, and
fstream.
2. ifstream: Provides input operations and opens files in read mode by default. It
inherits input-related functions such as get(), getline(), read(), seekg(),
and tellg() from istream.
3. ofstream: Provides output operations and opens files in write mode by default. It
inherits output-related functions such as put(), seekp(), tellp(), and write()
from ostream.
4. fstream: Supports both input and output operations by inheriting from both istream
and ostream, enabling simultaneous read and write access.
These classes and their functions enable us to perform the following operations on files:
Save changes.
When opening a file, we specify a file name and optionally a mode that determines the access
type. Each mode is a constant in the ios class, with the following common flags:
file.open("example.txt", ios::in);
if (file.is_open()) {
15 | P a g e
file.open("example.txt", ios::out);
if (file.is_open()) {
if (file.is_open()) {
ios::ate – Start at the end of the file. Without this flag, the initial position is the
beginning.
if (file.is_open()) {
ios::app – All output operations are appended to the end of the file.
if (file.is_open()) {
ios::trunc – Deletes previous content if a file is opened for output and already exists.
if (file.is_open()) {
Combining Flags: Use the bitwise OR operator (|) to combine flags as needed.
ofstream file;
Default Modes
Each stream class has a default mode when no mode argument is provided:
ofstream: ios::out
ifstream: ios::in
To perform file I/O in C++, include the <fstream> header and create objects of the required
stream classes.
Functions in the ofstream class provide several ways to output data to files:
Syntax: put(char);
Example:
ofstream obj;
obj.open("a.txt", ios::out);
2. write(): Writes a block of data to the file, which can be a string or an array.
Example:
Functions in the ifstream class provide ways to read data from files:
o Syntax: get(char);
o Example:
ifstream obj;
obj.open("a.txt", ios::in);
char ch;
Example:
18 | P a g e
char str[50];
3. read(): Reads a specified number of characters from the file into a variable.
Example:
Example: Program using the C++ file input and output class with open(), get(), put(),
close() methods for opening, reading from and writing to a file. Use append mode while
opening the file for writing.
#include <iostream>
#include <fstream> // Include fstream for file handling
using namespace std;
int main() {
fstream file; // Declare a file stream object
return 0;
}
Explanation of Code
Get pointer (get): Used for reading data from the file.
The file pointers start at specific positions based on the mode, and by default, they move
forward as reading or writing occurs. C++ provides several functions to manipulate and control
these pointers.
o The start parameter specifies the reference point, which can be:
o Example:
Example:
Example:
Example:
Note: For seekg() and tellg(), the file must be opened in read mode. For seekp() and
tellp(), it must be opened in write mode.
The following program demonstrates how to use various file I/O functions with a sample file
named "demo1.txt" containing the text ‘OBJECT ORIENTED PROGRAMMING’.
#include <iostream>
#include <fstream>
using namespace std;
int main() {
char ch;
ifstream fin;
fin.open("/path/to/demo1.txt"); // Update with actual path
if (!fin) {
cout << "Error opening file." << endl;
return 1;
}
cout << "Final position of get pointer: " << fin.tellg() << endl;
fin.close();
return 0;
}
Error and End-of-File Handling
When reading files sequentially, it’s important to check for the end of the file to avoid reading
beyond it. C++ provides the eof() function for this purpose. It returns true (1) if the end
of the file has been reached; otherwise, it returns false (0).
Syntax:
if (!obj.eof()) {
// Statements
}
23 | P a g e
Example:
while (!fin.eof()) {
fin.get(ch);
This approach ensures smooth file handling and prevents errors from attempting to read past
the end of the file.
In C++, the operators >> and << serve dual purposes. By default, they perform bitwise shifting,
but they are also overloaded to facilitate input/output operations with streams:
Extraction Operator (>>): Overloaded to allow cin to read input from the standard
input stream.
Insertion Operator (<<): Overloaded to allow cout to write output to the standard
output stream.
The insertion and extraction operators can be customized (overloaded) for user-defined classes,
enabling objects to interact directly with streams. These overloaded operators are often defined
as friend functions of the class to access private members.
Example:
#include <iostream>
using namespace std;
class Complex
{
private:
int real, imag;
public:
Complex(int r = 0, int i =0)
{ real = r; imag = i; }
24 | P a g e
int main(){
Complex c1;
cin >> c1;
cout << "The complex number is ";
cout << c1;
return 0;
}
Overview of cin and cout
cin: An instance of the istream class, cin uses the overloaded extraction operator
>> to take input from the standard input (keyboard).
cout: An instance of the ostream class, cout uses the overloaded insertion operator
<< to output data to the standard output (monitor).
These objects help facilitate stream-based input and output, enabling flexible formatting.
25 | P a g e
In-memory formatting allows you to treat a portion of memory as a stream. This technique can
be useful, for instance, in GUI applications where formatted text needs to be displayed in a
dialog box. Using in-memory streams, data can be composed and formatted in memory before
being passed to functions that display it on the screen.
Fixed-Size Buffer
To use in-memory formatting, include the sstream header file. In a fixed-size buffer, a char*
buffer is created, and an ostream object is linked to this memory, allowing you to write data
to memory just as you would to a file.
Dynamic-Size Buffer
For dynamic buffers, an ostringstream object can be created without an associated buffer,
allowing the object to allocate memory as needed. This object expands to hold any amount of
data you write into it.
#include <iostream>
#include <sstream>
#include <string>
using namespace std;
int main() {
ostringstream streamObj;
return 0;
}
In this example, the stream object automatically manages its size as data is inserted. This can
be particularly useful in applications where formatted text output is required for display on
various output devices.
C++ provides the ability to accept command-line arguments, allowing data to be passed to a
program directly from the operating system. This is particularly useful in command-line
interfaces like DOS or Linux.
To handle command-line arguments in a C++ program, the main function is defined with two
parameters:
argc: Stands for "argument count." It holds the number of arguments passed,
including the program name.
o argv[0] contains the program name (or an empty string if not available).
o argv[argc] is a NULL pointer that marks the end of the argument list.
Each element in argv can be treated as a C-string, or argv can be accessed as a 2D character
array.
This example demonstrates reading a file name from the command line and writing user-
provided content to it.
Assume a file named demo1.txt will be created or modified as specified by the user in the
command-line arguments.
Program Code:
27 | P a g e
#include <iostream>
#include <fstream>
using namespace std;
return 0;
}
Running the Program
Sample Output:
Enter Marks: 96
Roll No.: 21
Name: John
Marks: 96
This example illustrates how C++ command-line arguments can be used to dynamically specify
file names and facilitate various file operations.
1. Prompt the User for a Printer: The printerstream can prompt users to select a
printer.
2. Specify a Printer by Name: You can define a specific printer by its name.
3. Provide a Drawing Context: Optionally, you can use a drawing context if required by
the printer.
The output is sent to the printer when the printerstream instance is either disposed of or
when the end() method is called explicitly. This approach is straightforward, although limited
in functionality; page margins are the main customizable option.
Example Code
This example demonstrates how to use printerstream to print a simple document titled
"Test" and customize page margins.
#include "printerstream.h"
using namespace std;
int main() {
// Initialize output to a printer (e.g., PDFCreator)
printerstream<wchar_t> printer("PDFCreator");
return 0;
}
Explanation of Key Components
Content Printing: Text output is directed to the printer using standard output
formatting (<< operator).
Ending the Document: end() finalizes the print job and sends it to the printer
(optional if the instance will soon go out of scope).
1. Write a program to create file, read and write record into it. Every record contains
employee name, id and salary. Store and retrieve at least 3 data.
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
class Employee {
31 | P a g e
int ID;
float salary;
string name;
public:
void input() {
cout << "Enter name: ";
cin.ignore();
getline(cin, name);
cout << "Enter ID: ";
cin >> ID;
cout << "Enter salary: ";
cin >> salary;
}
in >> salary;
in.ignore(); // Ignore the newline character after salary
}
};
int main() {
const char* filename = "employees.txt";
Employee emp;
cout << "Enter information for 3 employees.\n";
for (int i = 0; i < 3; ++i) {
cout << "Employee " << (i + 1) << ":\n";
emp.input();
emp.writeToFile(fout);
}
fout.close();
cout << "\nData saved to file.\n\n";
return 0;
}
2. Define a class Person that has three a ributes viz name, gender and age. Write a C++
Program that writes an object to a file and reads an object from a file.
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
class Person {
string name;
char gender;
int age;
public:
// Method to input data for the person
void input() {
cout << "Enter name: ";
cin.ignore();
getline(cin, name);
cout << "Enter gender (M/F): ";
cin >> gender;
34 | P a g e
int main() {
const char* filename = "person.txt";
if (!fout) {
cerr << "Error opening file for writing." << endl;
return 1;
}
Person person;
cout << "Enter information for the person:\n";
person.input();
person.writeToFile(fout);
fout.close();
cout << "\nData saved to file.\n\n";
return 0;
}
3. Write a program to create files using constructor func on.
#include <iostream>
#include <fstream>
#include <string>
36 | P a g e
class FileCreator {
private:
ofstream file; // Output file stream
public:
// Constructor
FileCreator(const string& filename) {
file.open(filename); // Open the file
if (!file) {
cerr << "Error opening file: " << filename << endl;
} else {
cout << "File created: " << filename << endl;
// Write some sample data to the file
file << "This is a sample file created using a constructor
function.\n";
file << "Hello, World!" << endl;
}
}
// Destructor
~FileCreator() {
if (file.is_open()) {
file.close(); // Close the file
cout << "File closed." << endl;
}
}
};
int main() {
string filename;
37 | P a g e
return 0;
}
4. Write a program that returns the size in bytes of a program entered on the command line.
#include <iostream>
#include <fstream>
using namespace std;
if (argc >= 2) {
// Object to read source file
ifstream fin;
cout << "File Size = " << count << " Bytes\n"; // Added
space in the output
} else {
cout << "Error opening file: " << argv[1] << endl; //
Error message for file opening failure
}
} else {
cout << "Source file not found\n";
}
return 0;
}