Saturday, November 23, 2013

Extracting formatted input using stringstream

Description: The following program shows how to extract formatted input from a stringstream object.


#include <iostream>
#include <fstream>
#include <sstream>

/*
  Extracting formatted input using stringstream >> operator.

  While extracting input, if there are any errors it could set eofbit, badbit or failbit in its internal error state falgs.

  Then it checks its exception mask to decide wheter to throw an exception or not.

  For example if failbit is set in exception mask and  failbit was set during extraction then >> operation would

  throw an ios_base::failure exception.
*/

using namespace std;
void getexceptionmask(const stringstream& ss)
{

ios_base::iostate exceptionmask = ss.exceptions();


if(exceptionmask & ifstream::badbit)
{
cout << "badbit is set. If an operation on sstream causes this bit to be set, an exception of type ios_base::failure would be thrown.\n" ;
}

if(exceptionmask & ifstream::failbit)
{
cout << "failbit is set. If an operation on sstream causes this bit to be set, an exception of type ios_base::failure would be thrown.\n" ;
}
}

void checkerrorstate(const stringstream& ss)
{

if(ss.bad())
{
cout << "Bad bit is set. We failed to read an integer" << endl;
}

if(ss.fail())
{
cout << "Fail bit or Bad bit is set. We failed to read an integer" << endl;
}
}

int main(int argc, char** argv)
{

stringstream ss;

cout << "Printing the default exception mask." << endl;

getexceptionmask(ss);

cout << "Printing after setting badbit and failbit exception mask." << endl;

ss.exceptions(ifstream::badbit | ifstream::failbit);

getexceptionmask(ss);

cout << "Printing after clearing the exception mask." << endl;

/*  
*if exception mask  has only goodbit (which is zero) streams  do not throw exceptions due to error state flags being set
*/
ss.exceptions(ifstream::goodbit);

getexceptionmask(ss);

int n;

cout << "Trying to read an integer when the stream is empty." << endl;

ss >> n;

cout << "Checking if any of the error bits were set." << endl;

checkerrorstate(ss);

/*
* clearing the errot state.
*/

ss.clear();

cout << "Printing exception mask after setting fail bit." << endl;

ss.exceptions(ifstream::failbit);

getexceptionmask(ss);

cout << "Now again trying to read an integer. We should get an exception now." << endl;

ss >> n;

}

Output:

Printing the default exception mask.
Printing after setting badbit and failbit exception mask.
badbit is set. If an operation on sstream causes this bit to be set, an exception of type ios_base::failure would be thrown.
failbit is set. If an operation on sstream causes this bit to be set, an exception of type ios_base::failure would be thrown.
Printing after clearing the exception mask.
Trying to read an integer when the stream is empty.
Checking if any of the error bits were set.
Fail bit or Bad bit is set. We failed to read an integer
Printing exception mask after setting fail bit.
failbit is set. If an operation on sstream causes this bit to be set, an exception of type ios_base::failure would be thrown.
Now again trying to read an integer. We should get an exception now.
terminate called after throwing an instance of 'std::ios_base::failure'
  what():  basic_ios::clear

Aborted