Double -> C-String conversion

D

Der Andere

During every iteration in a loop, I need to convert a double value into a
char*. Simple type-casting did not work, so I thought of using
stringstreams. However, the stream would have to be *emptied* after each
iteration (and I could not conceive of a practical way doing that).

Cheers,
Matthias
 
R

Rolf Magnus

Der said:
During every iteration in a loop, I need to convert a double value
into a char*. Simple type-casting did not work, so I thought of using
stringstreams.

Sounds as if you want a string representation of your double. A char* is
not a string. It's a pointer to char, nothing less, nothing more.
However, the stream would have to be *emptied* after each iteration
(and I could not conceive of a practical way doing that).

Do the following:

thestream.str("");
 
K

Karthik

Der said:
During every iteration in a loop, I need to convert a double value into a
char*. Simple type-casting did not work, so I thought of using
stringstreams. However, the stream would have to be *emptied* after each
iteration (and I could not conceive of a practical way doing that).

How about using sprintf ?

sprintf(p, "%lf", doubleval);
// Remember to allocate memory to p before you do this.

HTH
 
D

Der Andere

During every iteration in a loop, I need to convert a double value
Sounds as if you want a string representation of your double. A char* is
not a string. It's a pointer to char, nothing less, nothing more.

C-string, yes. I thought I could indicate a c-string with char *: Would
char[] be better?
Do the following:

thestream.str("");

It works now, cheers :)

Matthias
 
J

Jeff Schwab

Rolf said:
Der Andere wrote:




Sounds as if you want a string representation of your double. A char* is
not a string. It's a pointer to char, nothing less, nothing more.




Do the following:

thestream.str("");

Alternatively:

thestream.str( ).clear( );
 
R

Rolf Magnus

Jeff said:
Alternatively:

thestream.str( ).clear( );

According to Stroustrup, this shouldn't empty the stream, because str()
returns a copy of the string.
 
R

Rolf Magnus

Der said:
Sounds as if you want a string representation of your double. A char*
is not a string. It's a pointer to char, nothing less, nothing more.

C-string, yes. I thought I could indicate a c-string with char *:
Would char[] be better?

No. Actually, char[] is only allowed if used as a paremter. I just
wanted to clarify that char* isn't C's string type. C doesn't have a
string type. Therefore, there is no built-in way to convert something
into a string, and that explains why casting to char* doesn't do what
you want.
 
J

Jack Klein

How about using sprintf ?

That's a possibility but...
sprintf(p, "%lf", doubleval);

In all versions of the ISO C standard prior to 1999, including the
1995 version that the C++ standard inherits from, "%lf" is an
ill-formed conversion specifier for the *printf() functions and
produces undefined behavior.

There is no need for separate conversion specifiers for float and
double in *printf, as floats are always promoted to double as is the
case for all optional parameters to all variadic functions in C and
C++.

The 1999 update to the C standard made the 'l' length modifier a no-op
with the all floating point conversion specifiers, but this is not
part of the current C++ standard. The "%lf" *printf conversion
specifier causes undefined behavior in C++.
 
J

John Harrison

Jeff Schwab said:
Alternatively:

thestream.str( ).clear( );

That doesn't work. It clears the error flags of the stream. That's what
clear does for any stream, it has nothing to do with emptying a string
stream.

john
 
J

John Harrison

Jack Klein said:
That's a possibility but...


In all versions of the ISO C standard prior to 1999, including the
1995 version that the C++ standard inherits from, "%lf" is an
ill-formed conversion specifier for the *printf() functions and
produces undefined behavior.

How did this misunderstanding become so widespread? So widespread in fact
that the C standard committee felt obliged to change the standard.

john
 
B

Brian Rodenborn

No. Actually, char[] is only allowed if used as a paremter. I just
wanted to clarify that char* isn't C's string type. C doesn't have a
string type. Therefore, there is no built-in way to convert something
into a string, and that explains why casting to char* doesn't do what
you want.


Nor does C++ have a string type. It has a library template instantiation
called. C has a string concept, it is not an intrinsic type just as C++'s is
not. That C string, and you will find the term defined in the C standard, is
an array or array-like region of char terminated by a null character.

To convert a double to such a string, the sprintf() function can be used. I
would recommend using C++ strstreams instead.


Brian Rodenborn
 
I

Ivan Vecerina

John Harrison said:
How did this misunderstanding become so widespread? So widespread in fact
that the C standard committee felt obliged to change the standard.

Because when you want to read a double value, you use:
sscanf(p, "%lf", &doubleval); // for float: ... "%f", &floatval)

The implicit conversion of variadic function parameters from
float to double does not apply to pointers, as used in scan functions.

Given that the implicit conversion exists in printf (the parameters
received are always double, never float), it kind of makes sense
that %f and %lf be made equivalent, or even that %lf be the primary
choice. (But as Jack pointed out, %lf is formally UB in C++98 and C90).


Regards,
Ivan
 
J

Jeff Schwab

Rolf said:
Jeff Schwab wrote:




According to Stroustrup, this shouldn't empty the stream, because str()
returns a copy of the string.

Whoops! You're absolutely right.
 
J

Jeff Schwab

John said:
That doesn't work. It clears the error flags of the stream. That's what
clear does for any stream, it has nothing to do with emptying a string
stream.

No, John, you've mistaken the clear() method of the stream for the
clear() method of the underlying stream. The str() method here returns
a string, not a stream.

This is a great example of why unnecessary abbreviations are such a bad
idea when choosing identifiers.
 
J

Jeff Schwab

John said:
That doesn't work. It clears the error flags of the stream. That's what
clear does for any stream, it has nothing to do with emptying a string
stream.

john

No, John, you're wrong. You've mistaken the clear() method of the
stream for the clear() method of the underlying stream. The str()
method here returns a string, not a stream. This does clear the string
representation of the stream's contents, not the stream's error flags.
(Unfortunately, as Rolf pointed out, it clears only a temporary copy of
the string, so the stream is unaffected. I wonder, why isnt the
temporary string const?)

This is a great example of why unnecessary abbreviations are such a bad
idea when choosing identifiers.
 
J

Jack Klein

How did this misunderstanding become so widespread? So widespread in fact
that the C standard committee felt obliged to change the standard.

john

How did "void main()" become so widespread, as it is considerably more
so than "%lf"?

The real problem is the lack of symmetry between the *printf and
*scanf families. Both "%f" and "%lf" are required for the *scanf
family of functions, which receive a pointer to the destination type
and therefore can convert to both float and double.

Given that, it would have been better to accept "%lf" in printf all
along, and many compilers do as an extension, but there are also some
(no idea on relative percentage) that choke on it, as the standard
entitles them to do.
 
L

L Russ

Der Andere said:
During every iteration in a loop, I need to convert a double value into a
char*. Simple type-casting did not work, so I thought of using
stringstreams. However, the stream would have to be *emptied* after each
iteration (and I could not conceive of a practical way doing that).

I'm not sure you need to "empty" the stream after each iteration,
maybe just construct a new one.

Maybe like this
----------------------------
#include <iostream>
#include <sstream>
int main() {
static const double x[] = { 0.5, 123.456789, -99.2 };
for(int i=0; i<sizeof(x)/sizeof(x[0]); i++) {
std::eek:stringstream ox;
ox << x;
std::cout
<< i << " " // number of item
<< x << " " // raw item
<< ox.str() << " " // item as string
<< ox.str().c_str() // item as char *
<< std::endl;
}
return 0;
}
----------------------------
The output is:

0 0.5 0.5 0.5
1 123.457 123.457 123.457
2 -99.2 -99.2 -99.2

HTH
LR
 

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

Forum statistics

Threads
473,756
Messages
2,569,540
Members
45,025
Latest member
KetoRushACVFitness

Latest Threads

Top