Wednesday, October 23, 2024

istreambuf_iterator


Overview
IOStream classes provides iterators for reading and writing raw without formatting from streams just like a containers. istreambuf_iterator enables reading from the streams.

Details
istreambuf iterators are input iterators that read successive characters from an input stream (such as cin).

They are constructed from a basic_istream object, to which they become associated, so that whenever operator++ is used on the iterator, it extracts a character from the stream (using operator>>).

Syntax
The syntax is as below. 

template< class CharT = char,
          class Traits = char_traits<CharT>
class istreambuf_iterator;

NameDescription
charTCharacter type of the associated istream object.
traitsCharacter traits of the associated istream object.

Members
 It defines following types.
member typedefinition
iterator_categoryinput_iterator_tag
value_typecharT
difference_typeTraits::off_type
pointerconst charT*
referenceconst charT&

Operation
An istreambuf_iterator  as an input iterator supports operators *, ++,->, == , and !=. 
istreambuf_iterator is a single-pass input iterator that reads successive objects of type charT  from the basic_istream object (such as cin) for which it was constructed, by internally calling the appropriate operator >>. The actual read operation is performed when the iterator is incremented, not when it is dereferenced. The first object is read when the iterator is constructed. Dereferencing only returns a copy of the most recently read object.

In other words, unlike in a list or a vector, the iterator solely depends on the current position of the stream iterator of the stream object. 

The default-constructed istreambuf_iterator is known as the end-of-stream iterator. When a valid istreambuf_iterator  reaches the end of the underlying stream, it becomes equal to the end-of-stream iterator. 

istreambuf_iterator does not skip whitespace. Also a sentry object is not constructed while reading.

istreambuf_iterator  class also has a subclass called proxy which can be converted back to istreambuf_iterator. It's returned by post-increment operator.

This can be clearly seen in the example below. 
istringstream in{"Hello, world"};
istreambuf_iterator<char> it{in}, end;
//ss:"Hello, world"
string ss{it, end};
 
// single-pass
istringstream s{"abc"};
istreambuf_iterator<char> i1{s}, i2{s};
//prints a a
cout << *i1 << " " << *i2 << endl;

//prints b b
++i1;
cout << *i1 << " " << *i2 << endl;

//prints c c
++i2;  
cout << *i1 << " " << *i2 << endl;

Functionality
Constructors
NameDescription
istreambuf_iterator()Default Constructor. Creates end of stream iterator.

Example:
istream_iterator eos;
istream_iterator( istream_type& s)
istream_iterator( istream_type *s)

Initializes the iterator, stores the address of stream s, and performs the first read from the input stream to initialize the cached value data member.
Example:
istringstream ss{"abcd"};
istreambuf_iterator<char>  it(ss);
//prints a
cout << *it  << endl;
istream_iterator (const istream_iterator& x)
copy constructor
Constructs an istream iterator, with the same istream reference and current value.
Example:
istringstream ss{"abcd"};
istreambuf_iterator<char>  it(ss), it2(it++);
//prints ba
cout << *it  << *it2 << endl;

Overloaded operators
NameExample
reference operator*() 
Returns a reference to the element pointed by the iterator.
Internally, the function returns the value the object stores as its current element.
Example:
istringstream ss{"abcd"};
istreambuf_iterator<char>  it(ss);
//prints a
cout << *it  << endl;
  1. istream_iterator& operator++()
  2. istream_iterator& operator++(int)
Reads a value from the underlying stream (using its operator>>) and stores it into the iterator object. If the read fails (the underlying stream's fail() returns true), the iterator becomes the end-of-stream iterator.
Example:
istringstream ss{"abcd"};
istreambuf_iterator<char>  it(ss), it2;

it2 = it++;
//prints b a
cout << *it  << " " << *it2 << endl;

it=++it2;
//prints c c
cout << *it  << " " << *it2  << endl;

No comments:

Post a Comment