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

conversion between string and numerical value

P: n/a
hi

i need a fast way to do lots of conversion that between
string and numerical value(integer, float, double...), and
boost::lexical_cast is useless, because it runs for a long time,
(about 60 times slower than corresponding C functions)
it's too expensive for my program.

is there any way([template] library?) to do this fast and safely,
please ?
(old C-style functions is unbecoming)

Sep 19 '07 #1
Share this Question
Share on Google+
14 Replies


P: n/a
Aman JIANG wrote:
i need a fast way to do lots of conversion that between
string and numerical value(integer, float, double...), and
boost::lexical_cast is useless, because it runs for a long time,
(about 60 times slower than corresponding C functions)
it's too expensive for my program.
So, use the C functions.
is there any way([template] library?) to do this fast and safely,
please ?
I don't know of any, but should be relatively easy for you to roll
your own, no?
(old C-style functions is unbecoming)
Why?

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Sep 19 '07 #2

P: n/a
Aman JIANG <Am*******@gmail.comwrites:
hi

i need a fast way to do lots of conversion that between
string and numerical value(integer, float, double...), and
boost::lexical_cast is useless, because it runs for a long time,
(about 60 times slower than corresponding C functions)
it's too expensive for my program.

is there any way([template] library?) to do this fast and safely,
please ?
(old C-style functions is unbecoming)
How about:

#v+
std::string toString(long value) {
char buffer[100];
sprintf(buffer, "%ld", value);
return std::string(buffer);
}

std::string toString(unsigned long value) {
char buffer[100];
sprintf(buffer, "%lu", value);
return std::string(buffer);
}

long atol(std::string str) { return atol(str.c_str()); }
double atof(std::string str) { return atof(str.c_str()); }
#v-

It's C++ all right.

--
Best regards, _ _
.o. | Liege of Serenly Enlightened Majesty of o' \,=./ `o
..o | Computer Science, Michal "mina86" Nazarewicz (o o)
ooo +--<mina86*tlen.pl>---<jid:mina86*chrome.pl>--ooO--(_)--Ooo--
Sep 19 '07 #3

P: n/a
On 9 20 , 12 47 , "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
(old C-style functions is unbecoming)

Why?
because its style, it doesn't support wchar_t, and template and so
on...

Sep 20 '07 #4

P: n/a
On 9 20 , 1 37 , Michal Nazarewicz <min...@tlen.plwrote:
How about:

#v+
std::string toString(long value) {
char buffer[100];
sprintf(buffer, "%ld", value);
return std::string(buffer);

}

std::string toString(unsigned long value) {
char buffer[100];
sprintf(buffer, "%lu", value);
return std::string(buffer);

}

long atol(std::string str) { return atol(str.c_str()); }
double atof(std::string str) { return atof(str.c_str()); }
#v-

It's C++ all right.
thank you :)
char buffer[100];
that "100" is a magic number.
and this cannot support wchar_t, too :(

Sep 20 '07 #5

P: n/a
Aman JIANG <Am*******@gmail.comwrites:
On 9 20 , 1 37 , Michal Nazarewicz <min...@tlen.plwrote:
>How about:

#v+
std::string toString(long value) {
char buffer[100];
sprintf(buffer, "%ld", value);
return std::string(buffer);
}

std::string toString(unsigned long value) {
char buffer[100];
sprintf(buffer, "%lu", value);
return std::string(buffer);
}
One more:

std::string toString(double value) {
char buffer[100];
sprintf(buffer, "%f", value);
return std::string(buffer);
}
>long atol(std::string str) { return atol(str.c_str()); }
double atof(std::string str) { return atof(str.c_str()); }
#v-

It's C++ all right.

thank you :)
> char buffer[100];
that "100" is a magic number.
Yep, its a number long enough to hold a string representation of
a (unsigned) long value.
and this cannot support wchar_t, too :(
Uhm? You can rewrite it to support it. Just replace char by wchar_t and
sprintf with swprintf but I'm not sure if you really need it since the
value is converted into std::string anyways.

--
Best regards, _ _
.o. | Liege of Serenly Enlightened Majesty of o' \,=./ `o
..o | Computer Science, Michal "mina86" Nazarewicz (o o)
ooo +--<mina86*tlen.pl>---<jid:mina86*chrome.pl>--ooO--(_)--Ooo--
Sep 20 '07 #6

P: n/a
Michal Nazarewicz a écrit :
Aman JIANG <Am*******@gmail.comwrites:
>On 9 20 , 1 37 , Michal Nazarewicz <min...@tlen.plwrote:
>>How about:

#v+
std::string toString(long value) {
char buffer[100];
sprintf(buffer, "%ld", value);
return std::string(buffer);
}
[snip]
It's C++ all right.
thank you :)
>> char buffer[100];
that "100" is a magic number.

Yep, its a number long enough to hold a string representation of
a (unsigned) long value.
You can use numeric_limits<>::digits10 to fit the size to you type.

// add one for \0 and for additional digit
// add one more for sign with signed
char buffer [std::numeric_limits<unsigned long>::digits10 + 2];

In fact, with traits, it should be possible to write a template.

Michael
Sep 20 '07 #7

P: n/a
On Sep 20, 1:55 pm, Michal Nazarewicz <min...@tlen.plwrote:
Aman JIANG <AmanJI...@gmail.comwrites:
On 9 20 , 1 37 , Michal Nazarewicz <min...@tlen.plwrote:
How about:
#v+
std::string toString(long value) {
char buffer[100];
sprintf(buffer, "%ld", value);
return std::string(buffer);
}
std::string toString(unsigned long value) {
char buffer[100];
sprintf(buffer, "%lu", value);
return std::string(buffer);
}
One more:
std::string toString(double value) {
char buffer[100];
sprintf(buffer, "%f", value);
return std::string(buffer);
}
long atol(std::string str) { return atol(str.c_str()); }
double atof(std::string str) { return atof(str.c_str()); }
#v-
It's C++ all right.
thank you :)
char buffer[100];
that "100" is a magic number.
Yep, its a number long enough to hold a string representation of
a (unsigned) long value.
On some machines. There's no guarantee (although it's likely to
be sufficient in the near future).

It's not necessarily large enough to hold a "%f" conversion of a
float, and it's not large enough to hold a "%f" conversion of a
double on the machines I usually work on.

I might add that there is no guarantee that sprintf is faster
than boost::lexical_cast, although it's likely *if*
boost::lexical_cast doesn't have partial specializations for
std::string (since in the general case, boost::lexical_cast must
do two conversions, and not just one).

More generally, you might try:

std::string
toString( double value )
{
std::ostringstream s ;
s << value ;
return s.str() ;
}

or if that's too slow:

std::string
toString( double value )
{
char buffer[ 100 ] ;
std::ostrstream s ;
s << value << std::ends ;
assert( s ) ;
return buffer ;
}

(This will at least cause an assertion failure, rather than
undefined behavior, if the converted string requires more than
99 characters. You can, of course, replace the assertion with
any other error handling you wish.)

If all else fails, you can try snprintf, which is not standard
C++, but is standard C99, and probably available with your
implementation (and allows for error checking as well).

Also, you probably want to use the "%g" format (the default for
iostream), unless you know that the input is in a very limited
range.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Sep 20 '07 #8

P: n/a
On Sep 20, 2:15 pm, Michael DOUBEZ <michael.dou...@free.frwrote:
Michal Nazarewicz a écrit :
Aman JIANG <AmanJI...@gmail.comwrites:
On 9 20 , 1 37 , Michal Nazarewicz <min...@tlen.plwrote:
How about:
>#v+
std::string toString(long value) {
char buffer[100];
sprintf(buffer, "%ld", value);
return std::string(buffer);
}
[snip]
It's C++ all right.
thank you :)
char buffer[100];
that "100" is a magic number.
Yep, its a number long enough to hold a string representation of
a (unsigned) long value.
You can use numeric_limits<>::digits10 to fit the size to you type.
The original poster also had a version for double.
numeric_limits<>::digits10 doesn't suffice there (especially for
"%f").
// add one for \0 and for additional digit
// add one more for sign with signed
char buffer [std::numeric_limits<unsigned long>::digits10 + 2];
In fact, with traits, it should be possible to write a template.
Possible, but rather tricky. Don't forget that the format
specifier would have to depend on the type. You'd end up having
to explicitly specialize the traits for each type, with as much
work as if you'd just written a separate function for each type.

Just another reason why nobody in their right mind would want to
use the printf family of functions.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Sep 20 '07 #9

P: n/a
James Kanze <ja*********@gmail.comwrites:
Possible, but rather tricky. Don't forget that the format
specifier would have to depend on the type. You'd end up having
to explicitly specialize the traits for each type, with as much
work as if you'd just written a separate function for each type.

Just another reason why nobody in their right mind would want to
use the printf family of functions.
There are plenty of people (including myself) who prefer C stdio to C++
streams.

--
Best regards, _ _
.o. | Liege of Serenly Enlightened Majesty of o' \,=./ `o
..o | Computer Science, Michal "mina86" Nazarewicz (o o)
ooo +--<mina86*tlen.pl>---<jid:mina86*chrome.pl>--ooO--(_)--Ooo--
Sep 20 '07 #10

P: n/a
James Kanze wrote:
std::string
toString( double value )
{
char buffer[ 100 ] ;
std::ostrstream s ;
s << value << std::ends ;
assert( s ) ;
return buffer ;
}
Looks like something is missing here.
1) Where is buffer used?
2) what is std::ends?
Sep 20 '07 #11

P: n/a

anon <an**@no.nowrote in message...
James Kanze wrote:
std::string
toString( double value )
{
char buffer[ 100 ] ;
std::ostrstream s ;
s << value << std::ends ;
assert( s ) ;
return buffer ;
}

Looks like something is missing here.
1) Where is buffer used?
In the 'return'! <G>

std::ostrstream s( buffer, 100 ) ; // ??
2) what is std::ends?
Manipulator: ends
Write `\0' (the string terminator character).

--
Bob R
POVrookie
Sep 20 '07 #12

P: n/a
On 9 20 , 8 29 , James Kanze <james.ka...@gmail.comwrote:
On some machines. There's no guarantee (although it's likely to
be sufficient in the near future).

It's not necessarily large enough to hold a "%f" conversion of a
float, and it's not large enough to hold a "%f" conversion of a
double on the machines I usually work on.

I might add that there is no guarantee that sprintf is faster
than boost::lexical_cast, although it's likely *if*
boost::lexical_cast doesn't have partial specializations for
std::string (since in the general case, boost::lexical_cast must
do two conversions, and not just one).

More generally, you might try:

std::string
toString( double value )
{
std::ostringstream s ;
s << value ;
return s.str() ;
}

or if that's too slow:

std::string
toString( double value )
{
char buffer[ 100 ] ;
std::ostrstream s ;
s << value << std::ends ;
assert( s ) ;
return buffer ;
}

(This will at least cause an assertion failure, rather than
undefined behavior, if the converted string requires more than
99 characters. You can, of course, replace the assertion with
any other error handling you wish.)

If all else fails, you can try snprintf, which is not standard
C++, but is standard C99, and probably available with your
implementation (and allows for error checking as well).

Also, you probably want to use the "%g" format (the default for
iostream), unless you know that the input is in a very limited
range.
Thank you :)

I think use 'stringstream' to do this work is still expensive,
although it must be faster than boost::lexical_cast. We know that
'strstream' was "deprecated" in C++98.

Is there another way to do this, no stream, and no old C-style
functions, please ?
(sorry my english is not well)

Sep 21 '07 #13

P: n/a
On Sep 20, 7:35 pm, "BobR" <removeBadB...@worldnet.att.netwrote:
anon <a...@no.nowrote in message...
James Kanze wrote:
std::string
toString( double value )
{
char buffer[ 100 ] ;
std::ostrstream s ;
s << value << std::ends ;
assert( s ) ;
return buffer ;
}
Looks like something is missing here.
1) Where is buffer used?
In the 'return'! <G>
std::ostrstream s( buffer, 100 ) ; // ??
Yep. That's what I meant. I've gotten so used to
std::ostringstream that I forgot. Even though that was the
whole point of the thing: use an on stack buffer, rather than a
dynamically allocated one.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Sep 21 '07 #14

P: n/a
James Kanze wrote:
On Sep 20, 1:55 pm, Michal Nazarewicz <min...@tlen.plwrote:
>Aman JIANG <AmanJI...@gmail.comwrites:
On 9 20 , 1 37 , Michal Nazarewicz <min...@tlen.plwrote:
How about:
>#v+
std::string toString(long value) {
char buffer[100];
sprintf(buffer, "%ld", value);
return std::string(buffer);
}
>std::string toString(unsigned long value) {
char buffer[100];
sprintf(buffer, "%lu", value);
return std::string(buffer);
}
>One more:
>std::string toString(double value) {
char buffer[100];
sprintf(buffer, "%f", value);
return std::string(buffer);
}
>long atol(std::string str) { return atol(str.c_str()); }
double atof(std::string str) { return atof(str.c_str()); }
#v-
>It's C++ all right.
thank you :)
char buffer[100];
that "100" is a magic number.
>Yep, its a number long enough to hold a string representation of
a (unsigned) long value.

On some machines. There's no guarantee (although it's likely to
be sufficient in the near future).

It's not necessarily large enough to hold a "%f" conversion of a
float, and it's not large enough to hold a "%f" conversion of a
double on the machines I usually work on.

I might add that there is no guarantee that sprintf is faster
than boost::lexical_cast, although it's likely *if*
boost::lexical_cast doesn't have partial specializations for
std::string (since in the general case, boost::lexical_cast must
do two conversions, and not just one).

More generally, you might try:

std::string
toString( double value )
{
std::ostringstream s ;
s << value ;
return s.str() ;
}

or if that's too slow:

std::string
toString( double value )
{
char buffer[ 100 ] ;
std::ostrstream s ;
s << value << std::ends ;
assert( s ) ;
return buffer ;
}
I do not understand this version. Where is the magic that modifies the
variable buffer? and how are buffer and the ostrstream s related? It looks
as though you return an uninitialized array of char.

(This will at least cause an assertion failure, rather than
undefined behavior, if the converted string requires more than
99 characters. You can, of course, replace the assertion with
any other error handling you wish.)

If all else fails, you can try snprintf, which is not standard
C++, but is standard C99, and probably available with your
implementation (and allows for error checking as well).

Also, you probably want to use the "%g" format (the default for
iostream), unless you know that the input is in a very limited
range.

Best

Kai-Uwe Bux
Sep 21 '07 #15

This discussion thread is closed

Replies have been disabled for this discussion.