skipws and <<

N

Norman Landis

This is something that has puzzled me for a while. How does C++ define
skipws and noskipws
in such a way that they can be used as pseudo-variables that setf and unsetf
a flag?

The reason I ask is that I am defining a class for unlimited-length integers
and have defined a
friend operator overload of << and I would like the user to be able to turn
on and turn off the
printing of commas delimiting groups of three digits.

I am at a loss as to how this can be done.
 
D

David Harmon

On Tue, 13 Dec 2005 18:17:05 -0500 in comp.lang.c++, "Norman Landis"
This is something that has puzzled me for a while. How does C++ define
skipws and noskipws
in such a way that they can be used as pseudo-variables that setf and unsetf
a flag?

The basic idea: they are functions, and operator<< is overloaded for
function types to apply the function on the stream.
 
S

Simon Biber

Norman said:
This is something that has puzzled me for a while. How does C++ define
skipws and noskipws
in such a way that they can be used as pseudo-variables that setf and unsetf
a flag?

The reason I ask is that I am defining a class for unlimited-length integers
and have defined a
friend operator overload of << and I would like the user to be able to turn
on and turn off the
printing of commas delimiting groups of three digits.

Here's a way to allow the user to turn on and off the printing of
commas. With a system like this in place, you can just write:
ExtendedInteger ei(100);
cout << noCommas << ei << endl;
cout << commas << ei << endl;

I have not implemented a full extended integer type, just the basics
necessary to demonstrate the use of the noCommas and commas things.

/* file commaprint.hpp */

#ifndef H_COMMAPRINT
#define H_COMMAPRINT

#include <iostream>

class Comma {};

class NoComma {};

extern Comma commas;
extern NoComma noCommas;

class ExtendedInteger
{
private:
long value;

public:
ExtendedInteger(long v);

friend std::eek:stream&
operator<<(std::eek:stream& s, const ExtendedInteger& ei);

ExtendedInteger& operator/=(const ExtendedInteger& rhs);
ExtendedInteger operator% (const ExtendedInteger& rhs) const;
bool operator!=(const ExtendedInteger& rhs) const;
int getIntValue() const;
};

std::eek:stream&
operator<<(std::eek:stream& s, const Comma& c);

std::eek:stream&
operator<<(std::eek:stream& s, const NoComma& nc);

#endif

/* end file commaprint.hpp */




/* file commaprint.cpp */

#include "commaprint.hpp"

#include <iostream>
#include <string>

static bool enableCommas;

Comma commas;
NoComma noCommas;

std::eek:stream&
operator<<(std::eek:stream& s, const Comma& c)
{
enableCommas = true;
return s;
}

std::eek:stream&
operator<<(std::eek:stream& s, const NoComma& nc)
{
enableCommas = false;
return s;
}

ExtendedInteger::ExtendedInteger(long a)
: value(a)
{}

std::eek:stream&
operator<<(std::eek:stream& s, const ExtendedInteger& ei)
{
ExtendedInteger a = ei;
std::string output;
char buf[5];
const char *format = enableCommas ? "%03d," : "%03d";
do
{
sprintf(buf, format, (a % 1000).getIntValue());
output.insert(0, buf);
a /= 1000;
}
while(a != 0);
if(enableCommas) output.erase(output.end() - 1);
if((output.begin())[0] == '0') output.erase(output.begin());
if((output.begin())[0] == '0') output.erase(output.begin());
return s << output;
}

ExtendedInteger&
ExtendedInteger::eek:perator/=(const ExtendedInteger& rhs)
{
value /= rhs.value;
return *this;
}

ExtendedInteger
ExtendedInteger::eek:perator% (const ExtendedInteger& rhs) const
{
return value % rhs.value;
}

bool
ExtendedInteger::eek:perator!=(const ExtendedInteger& rhs) const
{
return value != rhs.value;
}

int
ExtendedInteger::getIntValue() const
{
assert(value >= INT_MIN && value <= INT_MAX);

return int(value);
}

/* end file commaprint.cpp */




/* file test_driver.cpp */

#include "commaprint.hpp"

#include <iostream>

using namespace std;

int main(void)
{
ExtendedInteger i(1000000000);
do
{
i /= 10;
cout << " " << noCommas;
cout.width(12);
cout << i << " " << commas;
cout.width(14);
cout << i << endl;
}
while(i != 0);
return 0;
}

/* end file test_driver.cpp */
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,756
Messages
2,569,535
Members
45,008
Latest member
obedient dusk

Latest Threads

Top