By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
445,655 Members | 962 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 445,655 IT Pros & Developers. It's quick & easy.

skipws and <<

P: n/a
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.
Dec 13 '05 #1
Share this Question
Share on Google+
2 Replies


P: n/a
On Tue, 13 Dec 2005 18:17:05 -0500 in comp.lang.c++, "Norman Landis"
<nl*****@optonline.net> wrote,
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.

Dec 14 '05 #2

P: n/a
Norman Landis wrote:
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::ostream&
operator<<(std::ostream& 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::ostream&
operator<<(std::ostream& s, const Comma& c);

std::ostream&
operator<<(std::ostream& 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::ostream&
operator<<(std::ostream& s, const Comma& c)
{
enableCommas = true;
return s;
}

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

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

std::ostream&
operator<<(std::ostream& 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::operator/=(const ExtendedInteger& rhs)
{
value /= rhs.value;
return *this;
}

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

bool
ExtendedInteger::operator!=(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 */

--
Simon.
Dec 14 '05 #3

This discussion thread is closed

Replies have been disabled for this discussion.