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

Formating of floats using iostream

P: n/a
I'm trying to write floats to a file following a specific format (8
characters/record, and some other rules) and seem to have solved all
but one problem. There is no way of telling the maximum characters to
output. For positive numbers this is no problem since I can specify the
precision (number of digits not counting the decimal-point), however
when the number is negative the minus-sign does not count towars the
precision (which it shouldn't really), which has the effect that a
value that is written as 8 characters when positive is 9 when negative.
The following illustrates the problem:

#include <iostream>
#include <ios>

int main()
{
std::cout.precision(7);
std::cout.setf(std::ios_base::showpoint);

std::cout << 54.325617 << " ";
std::cout << -54.325617 << " ";
std::cout << 45.545 << " ";
float f = 3434;
std::cout << f << " ";

return 0;
}

This outputs "54.32562 -54.32562 45.54500 3434.000".

All but the second number is 8 characters long, does anyone have a
solution to this or will I have to make a test before writing each
number and see if it's negative, and then reduce precision to 6?

--
Erik Wikström

Nov 17 '06 #1
Share this Question
Share on Google+
4 Replies


P: n/a
er****@student.chalmers.se wrote:
I'm trying to write floats to a file following a specific format (8
characters/record, and some other rules) and seem to have solved all
but one problem. There is no way of telling the maximum characters to
output. For positive numbers this is no problem since I can specify the
precision (number of digits not counting the decimal-point), however
when the number is negative the minus-sign does not count towars the
precision (which it shouldn't really), which has the effect that a
value that is written as 8 characters when positive is 9 when negative.
The following illustrates the problem:

#include <iostream>
#include <ios>

int main()
{
std::cout.precision(7);
std::cout.setf(std::ios_base::showpoint);

std::cout << 54.325617 << " ";
std::cout << -54.325617 << " ";
std::cout << 45.545 << " ";
float f = 3434;
std::cout << f << " ";

return 0;
}

This outputs "54.32562 -54.32562 45.54500 3434.000".

All but the second number is 8 characters long, does anyone have a
solution to this or will I have to make a test before writing each
number and see if it's negative, and then reduce precision to 6?
Use std::setw in <iomanip>.

Cheers! --M

Nov 17 '06 #2

P: n/a
On 17 Nov, 14:01, "mlimber" <mlim...@gmail.comwrote:
eri...@student.chalmers.se wrote:
[snip]
All but the second number is 8 characters long, does anyone have a
solution to this or will I have to make a test before writing each
number and see if it's negative, and then reduce precision to 6?

Use std::setw in <iomanip>.
Yeah, so I thought at first, but according to the standard that's the
same as doing std::cout.width(8), which in turn sets the _minimul_
field width, not max. So it basically just tells the stream how many
fill-characters to put in if the field is too small :-(

--
Erik Wikström

Nov 17 '06 #3

P: n/a
er****@student.chalmers.se wrote:
On 17 Nov, 14:01, "mlimber" <mlim...@gmail.comwrote:
eri...@student.chalmers.se wrote:
[snip]
All but the second number is 8 characters long, does anyone have a
solution to this or will I have to make a test before writing each
number and see if it's negative, and then reduce precision to 6?
Use std::setw in <iomanip>.

Yeah, so I thought at first, but according to the standard that's the
same as doing std::cout.width(8), which in turn sets the _minimul_
field width, not max. So it basically just tells the stream how many
fill-characters to put in if the field is too small :-(
If you must maintain the 8 character width, drop the precision by 1,
either universally or only on negative numbers:

#include <iostream>
#include <sstream>
#include <iomanip>
using namespace std;

class HardWidth
{
public:
HardWidth( const double f, const unsigned width=8 )
{
const unsigned prec = ( f < 0 ? width - 2 : width - 1 );
m_oss << showpoint << setw( width-1 ) << setprecision( prec ) << f;
}

friend inline std::ostream& operator<<( std::ostream &os, const
HardWidth &h )
{
return os << h.m_oss.str();
}

private:
ostringstream m_oss;
};

int main()
{
cout << HardWidth( 12.3456789 ) << " ";
cout << HardWidth( -12.3456789 ) << " ";
return 0;
}

// Output: 12.34568 -12.3457

You could also turn on the plus sign by using std::showpos.

Cheers! --M

Nov 17 '06 #4

P: n/a
mlimber wrote:
er****@student.chalmers.se wrote:
>On 17 Nov, 14:01, "mlimber" <mlim...@gmail.comwrote:
>>eri...@student.chalmers.se wrote:
[snip]
>>>All but the second number is 8 characters long, does anyone have a
solution to this or will I have to make a test before writing each
number and see if it's negative, and then reduce precision to 6?
Use std::setw in <iomanip>.
Yeah, so I thought at first, but according to the standard that's the
same as doing std::cout.width(8), which in turn sets the _minimul_
field width, not max. So it basically just tells the stream how many
fill-characters to put in if the field is too small :-(

If you must maintain the 8 character width, drop the precision by 1,
either universally or only on negative numbers:
Then I'd argue that's a flaw in iostream formatting. In printf (yes, I
know it's not typesafe), you can specify %X.Ylf format. The amount of
hoop-jumping needed for setting widths and formatting in iostreams is
excessive.

Mind you, I *LIKE* iostreams. They're very useful, and much cleaner
than printf .... EXCEPT for field formatting on primitive types.
Nov 17 '06 #5

This discussion thread is closed

Replies have been disabled for this discussion.