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

formatting buffers

P: n/a
I want to get rid of my "sprintf" call, so I wrote the following
example, in which I have two problems:
(1) why do I need to inherit from "streambuf", and not just use it as a
local in my "ToBuff" function (I get a protected constructor error)?
(2) I fail to get the output of the formatting in my C buffer, the
output of the program is:
string is: 100
buffer is: hello world
When I hoped to get:
string is: 100
buffer is: 100

note: the "ToString" function is not a real option where large buffers
should be allocated outside the class in "C style" code

the code:
///////////////////////////////////////////////////////////
#include <ostream>
#include <sstream>
#include <stdio.h>
#include <iostream>
using namespace std;

template <typename T>
class A : public streambuf
{
public:
A(const T& t) : m_value(t) {}

char* ToBuff(char* szBuff, int nSize)
{
pubsetbuf(szBuff, static_cast<streamsize>(nSize));
ostream os(this);
os << m_value << ends;
return szBuff;
}

string ToString() const
{
ostringstream ost(ostringstream::out);
ost << m_value << ends;
return ost.str();
}

private:
T m_value;
};

int main()
{
char buff[32]="hello world";

A<double> a(99.99999);

cout << "string is: " << a.ToString() << endl;
printf("buffer is: %s\n", a.ToBuff(buff,32));

return 0;
}

Nov 22 '05 #1
Share this Question
Share on Google+
3 Replies


P: n/a
yuvalif wrote:
I want to get rid of my "sprintf" call, so I wrote the following
example, in which I have two problems:
(1) why do I need to inherit from "streambuf", and not just use it as a
local in my "ToBuff" function (I get a protected constructor error)?
(2) I fail to get the output of the formatting in my C buffer, the
output of the program is:
string is: 100
buffer is: hello world
When I hoped to get:
string is: 100
buffer is: 100

note: the "ToString" function is not a real option where large buffers
should be allocated outside the class in "C style" code

the code:
///////////////////////////////////////////////////////////
#include <ostream>
#include <sstream>
#include <stdio.h>
#include <iostream>
using namespace std;

template <typename T>
class A : public streambuf
{
public:
A(const T& t) : m_value(t) {}

char* ToBuff(char* szBuff, int nSize)
{
pubsetbuf(szBuff, static_cast<streamsize>(nSize));
ostream os(this);
os << m_value << ends;
return szBuff;
}

string ToString() const
{
ostringstream ost(ostringstream::out);
This is more simply written

ostringstream ost;
ost << m_value << ends;
No need for ends with streamstream. In fact it is incorrect, unless you
really do want a nul byte included in your C++ string.

ost << m_value;
return ost.str();
}

private:
T m_value;
};

int main()
{
char buff[32]="hello world";

A<double> a(99.99999);

cout << "string is: " << a.ToString() << endl;
printf("buffer is: %s\n", a.ToBuff(buff,32));

return 0;
}


Basically you are misusing streambuf. It's designed as a base for stream
buffers, not for converting values to strings. The class you do need is
ostrstream.

#include <strstream>

char* ToBuff(char* szBuff, int nSize)
{
ostrstream ost(szBuff, nSize);
ost << m_value << ends;
return szBuff;
}

Don't much like your class design either, I would make these two
template functions.

template <class T>
string toString(const T& x)
{
...
}

template <class T>
char* toBuffer(const T& x, char* buf, int size)
{
...
}

Seems easier to use to me.

All code untested.

john
Nov 22 '05 #2

P: n/a
thanks john, working fine.

Two questions:
(1) My compiler (gcc4.0) warn me that: <strstream> is depreciated, any
idea for another include?
(2) Regarding the design, if I already have a template class, why
shouldn't it have a member function for the conversion?

Yuval.

Nov 22 '05 #3

P: n/a
yuvalif wrote:
thanks john, working fine.

Two questions:
(1) My compiler (gcc4.0) warn me that: <strstream> is depreciated, any
idea for another include?
It is deprecated, but personally I wouldn't worry. It still has
legitimate uses. But if you really want to avoid it then I would try
something like this

char* ToBuff(char* szBuff, int nSize)
{
ToString().copy(szBuff, nSize);
return szBuff;
}

In fact maybe that is preferable anyway.

(2) Regarding the design, if I already have a template class, why
shouldn't it have a member function for the conversion?
I was suggesting that you replace the template class with two template
functions. But if you have the template class already for other reasons
then fine.

Yuval.


john
Nov 22 '05 #4

This discussion thread is closed

Replies have been disabled for this discussion.