Siksha Sarovar

Siksha Sarovar (sikshasarovar.com) is a free educational web application that helps students in India learn programming and prepare for academic and competitive exams. The platform offers structured coding courses (C, C++, Python, Java, HTML, CSS, PHP, Power BI, AI, Machine Learning, Data Science), complete university curriculum notes for BCA/MCA students with previous year question papers, Class 10 and Class 12 CBSE/HBSE school notes, and dedicated preparation material for SSC, UPSC, Banking, Railway and other government exams. Browsing the site is completely free and requires no account. Users may optionally sign in with Google solely to save their learning progress, quiz scores and personal preferences across devices.

Privacy Policy | Terms of Service | Contact Siksha Sarovar | About Siksha Sarovar

v4.0.9 · PWA
Siksha Sarovar logo
Siksha Sarovar
Your Learning Universe

Siksha Sarovar is a free e-learning platform for coding courses, BCA university notes and competitive exam preparation. Optional Google sign-in saves your learning progress across devices.

Initializing knowledge base…
Compiling modules 0%

4.3 C++ Streams — Classes, I/O Operations & Manipulators

Lesson 21 of 22 in the free Object Oriented Programming with C++ notes on Siksha Sarovar, written by Rohit Jangra.

4.3 C++ Streams

What is a Stream?

A stream is an abstraction for a sequence of bytes flowing between a program and a device (keyboard, screen, file, network). C++ I/O is stream-based — the same operators (<<, >>) work for any stream.

   Source → Stream → Destination
DirectionExamples
InputKeyboard, file, network → program
OutputProgram → screen, file, network

---

The C++ Stream Class Hierarchy

                    ios_base
                       │
                       ▼
                      ios
                     /   \
                    /     \
                istream    ostream
                |    \   /    |
               /      iostream  \
              /         |        \
        ifstream   fstream      ofstream
        istringstream stringstream ostringstream
ClassHeaderRole
ios_base<ios>Base format flags
ios<ios>Generic stream state
istream<istream>Input stream
ostream<ostream>Output stream
iostream<iostream>Bidirectional
ifstream<fstream>File input
ofstream<fstream>File output
fstream<fstream>File input + output
stringstream<sstream>In-memory string

---

Predefined Stream Objects

ObjectTypeConnected toBuffered
cinistreamKeyboard (stdin)Line-buffered
coutostreamScreen (stdout)Line/full-buffered
cerrostreamScreen (stderr)Unbuffered — appears immediately
clogostreamScreen (stderr)Buffered

Plus wide-character variants: wcin, wcout, wcerr, wclog (for wchar_t).

---

Basic I/O Operations

Output with << (insertion operator)

cout << "Hello";              // string literal
cout << 42;                   // int
cout << 3.14;                 // double
cout << 'A';                  // char
cout << endl;                 // newline + flush
cout << "Name: " << name << ", Age: " << age << endl;  // chained

Input with >> (extraction operator)

int age;
string name;

cin >> age;                   // reads an int
cin >> name;                  // reads a word (no spaces)
cin >> age >> name;           // both, in order

>> skips leading whitespace and stops at next whitespace.

Reading a line with spaces — getline

string fullName;
getline(cin, fullName);       // reads until newline

Reading single character — get()

char c;
cin.get(c);                   // reads one character (including whitespace)

Writing single character — put()

cout.put('A');                // outputs A

---

Unformatted I/O

MethodPurpose
cin.get()Read one character
cin.get(buf, size)Read up to size-1 chars
cin.getline(buf, size)Read line into char buffer
cin.read(buf, n)Read exactly n bytes (binary)
cin.ignore(n)Skip n characters
cin.peek()Look at next char without consuming
cin.putback(c)Put back one character
cin.gcount()Number of characters last read
cout.put(c)Write one character
cout.write(buf, n)Write exactly n bytes (binary)

---

Manipulators

Manipulators are functions that modify stream state. Used with << or >>.

Common manipulators

#include <iomanip>     // for setw, setprecision, etc.

int main() {
    double pi = 3.141592653589;

    cout << pi << endl;                          // 3.14159 (default 6 digits)
    cout << setprecision(4) << pi << endl;       // 3.142
    cout << fixed << setprecision(2) << pi;      // 3.14
    cout << endl;

    cout << setw(10) << "Hi" << endl;            // "        Hi" (right-aligned, width 10)
    cout << setw(10) << left << "Hi" << endl;    // "Hi        " (left-aligned)
    cout << setfill('*') << setw(8) << 42 << endl;  // "******42"

    cout << hex << 255 << endl;                  // ff
    cout << oct << 8 << endl;                    // 10
    cout << dec << 255 << endl;                  // 255

    cout << boolalpha << true << endl;           // true (not 1)
    cout << showpos << 42 << endl;               // +42

    return 0;
}

Manipulator categories

CategoryExamples
Widthsetw(n)
Precisionsetprecision(n), fixed, scientific
Basehex, oct, dec, showbase
Alignmentleft, right, internal
Fillsetfill(c)
Booleanboolalpha, noboolalpha
Signshowpos, noshowpos
Caseuppercase, nouppercase
Flushendl, flush, ends
Whitespaceskipws, noskipws

Custom manipulators

// Simple manipulator — function taking and returning ostream&
ostream& tab(ostream& os) {
    return os << "\t";
}

cout << "Name" << tab << "Age";       // "Name\tAge"

---

Stream State / Error Checking

Streams maintain state flags:

FlagMeaning
goodbitAll OK
eofbitEnd-of-file reached
failbitFormat error (e.g., reading "abc" into int)
badbitStream corrupted (low-level I/O error)

Check methods

if (cin.good()) { /* all OK */ }
if (cin.eof())  { /* end of file */ }
if (cin.fail()) { /* format error or EOF */ }
if (cin.bad())  { /* serious error */ }
if (cin)        { /* shorthand: not fail and not bad */ }

Idiomatic input loop

int n;
while (cin >> n) {            // continues until extraction fails
    cout << n * 2 << endl;
}

When cin >> n fails (non-int input or EOF), the conversion to bool returns false.

Recovering from error

int n;
cin >> n;
if (cin.fail()) {
    cin.clear();                                        // clear error flags
    cin.ignore(numeric_limits<streamsize>::max(), '\n');  // discard bad input
}

---

stringstream — In-Memory Streams

A stringstream reads/writes to a string instead of console or file. Useful for parsing or building strings.

#include <sstream>

// Read from string (like cin):
istringstream iss("42 3.14 hello");
int    n;
double d;
string s;
iss >> n >> d >> s;
cout << n << " " << d << " " << s;   // 42 3.14 hello

// Write to string (like cout):
ostringstream oss;
oss << "Value is " << 42;
string result = oss.str();           // "Value is 42"

Common uses

  • Parsing input fields
  • Building log messages
  • Number-to-string and string-to-number conversion (before C++11's std::to_string)

---

Overloading << and >> for User-Defined Types

Already mentioned in Unit III; here's the full pattern:

class Point {
private:
    int x, y;
public:
    Point(int a = 0, int b = 0) : x(a), y(b) {}

    friend ostream& operator<<(ostream& os, const Point& p);
    friend istream& operator>>(istream& is, Point& p);
};

ostream& operator<<(ostream& os, const Point& p) {
    os << "(" << p.x << ", " << p.y << ")";
    return os;
}

istream& operator>>(istream& is, Point& p) {
    is >> p.x >> p.y;
    return is;
}

int main() {
    Point p(3, 4);
    cout << p << endl;       // (3, 4)

    Point p2;
    cin >> p2;
    cout << p2;
    return 0;
}

Key points:

  • Returns the stream reference → enables chaining
  • Friend (or non-member) because left operand is the stream
  • For output, take const T& (no modification); for input, take T& (modifies)

---

Buffered vs Unbuffered I/O

Buffered (default for cout)

  • Output collected in a buffer until flushed
  • Flushed by: endl, flush, buffer full, program end

Unbuffered (cerr)

  • Each character written immediately
  • For error output that must appear even if program crashes
cout << "Hello";           // may not appear yet
cout << flush;              // forces flush
cout << "World" << endl;    // newline + flush

cerr << "Error!";           // appears immediately

\n vs endl:

  • \n — just newline character
  • endl — newline + flush (slower but ensures output appears)

For performance, prefer \n inside loops; use endl when you need immediate output.

---

Synchronisation with C stdio

By default, C++ cin / cout are synchronised with C's scanf / printf — allowing mixed use. This has a performance cost.

ios_base::sync_with_stdio(false);    // disable sync — faster I/O
cin.tie(nullptr);                     // untie cin from cout

After these calls, cin / cout are 2-5× faster (relevant for competitive programming).

---

Complete Example — Reading & Printing Student Records

#include <iostream>
#include <iomanip>
using namespace std;

struct Student {
    string name;
    int    id;
    double marks;
};

int main() {
    int n;
    cout << "Enter number of students: ";
    cin >> n;

    Student* students = new Student[n];

    for (int i = 0; i < n; i++) {
        cout << "Student " << i + 1 << "\n";
        cout << "  Name: ";
        cin >> students[i].name;
        cout << "  ID: ";
        cin >> students[i].id;
        cout << "  Marks: ";
        cin >> students[i].marks;
    }

    cout << "\n" << left
         << setw(20) << "Name"
         << setw(10) << "ID"
         << setw(10) << "Marks" << "\n";
    cout << string(40, '-') << "\n";

    for (int i = 0; i < n; i++) {
        cout << left
             << setw(20) << students[i].name
             << setw(10) << students[i].id
             << fixed << setprecision(2) << students[i].marks << "\n";
    }

    delete[] students;
    return 0;
}

---

Study deep

  1. endl flushes — \n does not. For tight loops outputting many lines, prefer \n. endl is for when output must be visible (interactive prompts, error messages, before crashes).
  1. >> skips whitespace; get / getline don't. Mix carefully. After cin >> age, a newline remains in the buffer — getline reads it as empty. Fix: cin.ignore();
  1. Streams are stateful. Stream flags persist across calls (e.g., hex). Forgetting to reset them causes confusing output.
  1. Modern std::format (C++20) — like Python's f-strings:
cout << format("Hello {}, you are {} years old", name, age);

Type-safe alternative to printf.

  1. Boost.Format and std::format for complex output. <iomanip> is verbose; std::format is concise and modern. For now, IPU expects <iomanip> style.

Key Terms — Lesson 4.3

The terms below cover C++ streams — the stream class hierarchy, I/O operations, manipulators — every PYQ on streams expects fluent use.

Stream — An abstraction representing a sequential flow of bytes to or from a source/destination. In C++ a stream is an object of a class derived from ios_base. Streams unify console, file, and string I/O behind the same operators (<<, >>).

ios / ios_base — The root of the C++ stream class hierarchy. Provides the common state (flags, format, error bits, locale) used by all streams. Application code rarely uses it directly; it sits one level beneath istream/ostream.

istream / ostream / iostream — Three core stream classes. istream is for input (cin is an istream). ostream is for output (cout, cerr, clog are ostreams). iostream is for bidirectional I/O (combines both).

Stream Hierarchy — The inheritance graph: iosistream/ostreamiostream (bidirectional). File streams (ifstream, ofstream, fstream) and string streams (istringstream, ostringstream, stringstream) derive from the corresponding classes.

Predefined Stream Objects — Four stream instances declared in <iostream>: cin (standard input), cout (standard output, buffered), cerr (standard error, unbuffered), clog (standard error, buffered).

cin — Standard Input Stream — The istream object bound to stdin (keyboard / piped input). Reading with >> skips leading whitespace and stops at the first whitespace.

cout — Standard Output Stream — The ostream object bound to stdout (terminal / piped output). Buffered by default — output may not appear until the buffer flushes (endl, flush, program end, full buffer).

cerr — Standard Error Stream (Unbuffered) — The ostream bound to stderr, unbuffered so error messages appear immediately. Good for urgent diagnostics; not affected by cout redirection.

clog — Standard Error Stream (Buffered) — A buffered counterpart of cerr for log messages where immediate visibility is less critical.

Insertion Operator << — In stream context, the operator that inserts the right operand into the left stream. cout << x writes x to cout. Returns the stream by reference to enable chaining (cout << a << b << c).

Extraction Operator >> — In stream context, the operator that extracts a value from the left stream into the right variable. cin >> x reads from cin into x. Returns the stream by reference; checking the returned stream in a boolean context indicates success.

Manipulator — A function (or function-like object) applied to a stream to modify its behaviour. Includes endl (newline + flush), flush (force buffer flush), setw(n) (field width), setfill(c) (fill character), setprecision(n) (decimal precision), fixed / scientific (notation), hex / oct / dec (number base), boolalpha (print bools as true/false), left/right/internal (alignment).

<iomanip> Header — The standard header providing parameterised manipulatorssetw, setprecision, setfill, setbase. Manipulators without parameters live in <iostream>.

endl vs "\n" — Both insert a newline. endl also flushes the output buffer (slower but ensures immediate visibility). "\n" just writes the newline character. Use \n in tight loops, endl for prompts and error messages.

Buffered I/O — I/O that accumulates data in a memory buffer before transmitting. cout is buffered; output may sit in the buffer until endl, flush, a full buffer, or program termination forces it out. Improves throughput at the cost of latency.

Flushing — Forcing the stream buffer to write its contents to the underlying device. Achieved by endl, flush manipulator, or stream.flush() method. Important before crashes (so logged errors actually appear) and in interactive prompts.

Format State / Stream State — A set of persistent flags carried by the stream object — number base, precision, width, alignment, fill character, boolalpha. Changes persist across operations until explicitly reset. stream.setf(), stream.unsetf(), stream.flags() manipulate them.

Error State Flags — Stream state bits indicating I/O outcome. good (no errors), eof (end-of-file reached), fail (logical error — wrong type read), bad (irrecoverable I/O error — file gone). Checked via stream.good(), stream.eof(), stream.fail(), stream.bad().

getline() — A function that reads a full line (including spaces) from an istream until a delimiter (default \n). getline(cin, line);. Avoids the whitespace-stops-extraction behaviour of >>.

get() / put() — Character-level stream methods. cin.get(c) reads one character (including whitespace). cout.put(c) writes one character. The character-level equivalents of >> and <<.

read() / write() — Block-level binary stream methods. stream.read(buf, n) reads up to n raw bytes. stream.write(buf, n) writes n raw bytes. Used heavily in binary file I/O (next lesson).

Operator Overloading for Streams — Defining operator<< and operator>> for a user-defined class to support cout << myObj and cin >> myObj. Implemented as friend functions because the left operand is a stream (not the user class). Returns the stream by reference for chaining.

String Stream (stringstream) — A stream whose underlying source/destination is a std::string, not a file or console. istringstream for input, ostringstream for output, stringstream for both. Useful for parsing numbers from text, formatting strings, in-memory I/O.

Synchronisation with C Streams — By default, cin/cout are synchronised with stdin/stdout so they can be mixed. Disabling this with ios_base::sync_with_stdio(false); makes them 2–5× faster — relevant for competitive programming. cin.tie(nullptr); further decouples cin from cout flushing.

Stream Tying — A mechanism where one stream automatically flushes another before any operation. By default, cin is tied to cout, so reading from cin first flushes cout (ensuring prompts are visible before the user types).

std::format (C++20) — A modern, type-safe formatting library inspired by Python's f-strings. format("Hello {}, age {}", name, age). The C++20 alternative to verbose iomanip-based formatting or unsafe printf.

---

PYQ pattern: "Explain C++ stream classes and their hierarchy." — Define stream; show diagram (ios → istream/ostream → iostream → fstream); list predefined objects (cin, cout, cerr, clog).
PYQ pattern: "What are manipulators in C++? Give examples." — Define; setw, setprecision, hex, fixed, endl; show code using <iomanip>.
PYQ pattern: "Overload << and >> operators for a class." — Use friend functions; return reference to stream; example with Point or Complex.