Linguaggio C++

Libreria Streambuf

Introduzione alla libreria streambuf del C++: il buffer sottostante agli stream di input e output.

La libreria <streambuf> contiene la classe std::streambuf, la struttura interna che gestisce il buffer di tutti gli stream del C++ (cin, cout, file stream, string stream, ecc.).

Normalmente non si usa direttamente, ma è fondamentale per capire come funzionano gli stream, oppure quando si vuole:

  • creare un nuovo tipo di stream personalizzato
  • reindirizzare temporaneamente cout o cin
  • modificare il comportamento dei buffer di input/output

1️⃣ Inclusione della libreria


#include <streambuf>

È inclusa automaticamente da <iostream>, ma può essere usata separatamente.


2️⃣ Cos è uno stream buffer?

Ogni stream del C++ (cin, cout, fstream, stringstream...) usa internamente un oggetto di tipo std::streambuf per gestire:

  • i caratteri in ingresso
  • i caratteri in uscita
  • il buffer temporaneo

Gli stream sono solo interfacce di alto livello che si appoggiano a streambuf.


3️⃣ Funzioni principali di streambuf

MetodoDescrizione
sbumpc()Legge un carattere dal buffer (e avanza)
sgetc()Legge un carattere senza avanzare
sputc(c)Scrive un carattere nel buffer di output
sgetn(buf, n)Legge n caratteri nel buffer specificato
sputn(buf, n)Scrive n caratteri nel buffer
pubsync()Sincronizza il buffer (flush)
in_avail()Ritorna quanti caratteri sono disponibili per la lettura

4️⃣ Esempio: leggere caratteri dal buffer di cin


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

int main() {
    streambuf* sb = cin.rdbuf();

    cout << "Scrivi qualcosa: ";
    char c = sb->sbumpc();

    cout << "Primo carattere letto: " << c;
}

In questo esempio si accede direttamente al buffer interno di cin.


5️⃣ Esempio: reindirizzare cout temporaneamente


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

int main() {
    stringstream ss;

    streambuf* oldbuf = cout.rdbuf(ss.rdbuf());
    cout << "Questo va nello stringstream!";

    cout.rdbuf(oldbuf); // ripristina cout

    cout << "Contenuto catturato: " << ss.str();
}

Tecnica utile per test, logging o salvataggio in memoria.


6️⃣ Esempio: scrivere direttamente in un file buffer


#include <fstream>
#include <streambuf>
using namespace std;

int main() {
    ofstream file("test.txt");
    streambuf* sb = file.rdbuf();

    sb->sputc('A');
    sb->sputc('B');
    sb->pubsync();   // flush

    file.close();
}

Si scrivono caratteri nel file bypassando l'ostream.

LABORATORIO

Uso avanzato del buffer con streambuf

In questo laboratorio esplorerai il funzionamento interno dei buffer degli stream usando direttamente streambuf. Effettuerai letture e scritture a basso livello e reindirizzerai lo stream di output.


1 Leggere il primo carattere dal buffer

Usa sbumpc() per leggere il primo carattere inserito dall utente.


streambuf* sb = cin.rdbuf();
char c = sb->sbumpc();
cout << "Primo carattere: " << c;

2 Controllare i caratteri disponibili

Mostra quanti caratteri sono nel buffer prima della lettura.


streambuf* sb = cin.rdbuf();
cout << "Caratteri disponibili: " << sb->in_avail();

3 Reindirizzare cout

Fai scrivere cout dentro uno stringstream.


stringstream ss;
streambuf* old = cout.rdbuf(ss.rdbuf());
cout << "Test di reindirizzamento";
cout.rdbuf(old);
cout << ss.str();

4 Esercizi

  • Cattura tutto l output di un programma e salvalo in una stringa.
  • Scrivi un mini logger che intercetta cout e aggiunge un timestamp prima di ogni messaggio.
  • Leggi un intero file carattere per carattere usando sbumpc().
  • Implementa un tuo streambuf personalizzato (solo se vuoi approfondire molto).