Question about setprecision

This program reads temperatures from a file and converts then from F to C. The problem is for some reason if the temperature is negative or has a decimal point, it comes out something like 1e+002. If I don't use setprecision this doesn't happen. I'm sure it's something little I've overlooked, but I've been reading the forums all day trying to find someone with a similar problem and haven't yet.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include <fstream>
#include <iomanip>
#include <iostream>
#include <string>
using namespace std;

#include <cmath>

int main()
{

  //variable for the degree symbol
  char degreeSymbol = 0xF8;

  ifstream fin;
  fin.open("temps.txt");
  if (!fin.good()) throw "I/O error";


  // end of file loop to check for sentinel value of -999
  while (fin.good())
  {
    // read an int from one line of an input file
    float a;
    fin >> a;
    fin.ignore(1000, 10);

    // sentinel value
    if (a == -999) break;

    //programmer supplied formula for conversion
    float b = 1.8 * a + 32;

    //unformatted output
    cout << a << degreeSymbol << " Celsius equals ";

    //formatting output to 1 decimal place
    cout.setf(ios::fixed|ios::showpoint);
    cout << setprecision(1);

    //formatted output
    cout << b << degreeSymbol << " Fahrenheit." << endl << endl;
    cout.unsetf(ios::fixed|ios::showpoint);
  }

  fin.close();
}
Have you tried using cout.precision() instead? Maybe that's not the preferred way or bad form, but that's the syntax I was taught.
You have changed the formatting for b but not for a.
@Flakjacketz

I found that the program works correctly, if you move cout.unsetf(ios::fixed | ios::showpoint); to the point after fin.close();

Also, you could get rid of the -999 check. The program will end after converting the last temperature it reads in the list.

@Peter87
There is no need for 'a' to be converted to anything, since 'a' IS the temperature being converted
Last edited on
I'm still having an issue whether I leave the cout.unsetf(ios::fixed | ios::showpoint); where it is or move it to after the fin.close(); . Maybe showing my inputs will help, If I use these inputs in my temps.txt file with the unset where it is
1
2
3
4
5
6
100
-40
100.01
5
0
-999

These are the inputs that get echo'd to the console screen
1
2
3
4
5
100
-4e+001
1e+002
5
0

All of the converted outputs are correct, it's just the inputs that it shows wrong

If i move the cout.unsetf(ios::fixed | ios::showpoint); to after the fin.close(); , all of the input temps after the first one get truncated to one decimal place like this
1
2
3
4
5
100
-40.0
100.0
5.0
0.0


the sentinal -999 is only in there to show that it won't print it
@Flakjacketx

You do have setprecision(), set to 1, so it will be truncated to just 1 decimal point. I also changed the declaration of a and b, to a double. I got tired of the warnings during compiling.

Here's the tweaking I did.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include <fstream>
#include <cmath>
#include <iomanip>
#include <iostream>
#include <string>
using namespace std;



int main()
{

	//variable for the degree symbol
	char degreeSymbol = '\xF8';
	double a, b;
	ifstream fin;
	fin.open("temps.txt");
	if (!fin.good())
	{
		cout << "Temperature list, could not be found. Aborting." << endl;
		return 1;
	}


	// end of file loop to check for sentinel value of -999
	while (fin.good())
	{
		// read an int from one line of an input file
		fin >> a;
		fin.ignore(2, '\n');// Just my style of doing it. Nothing wrong with yours

		// sentinel value
		//if (a == -999) break;

		//programmer supplied formula for conversion
		b = 1.8 * a + 32;

		//unformatted output
		cout << a << degreeSymbol << " Celsius equals ";

		//formatting output to 1 decimal place
		cout.setf(ios::fixed | ios::showpoint);
		cout << setprecision(1);

		//formatted output
		cout << b << degreeSymbol << " Fahrenheit." << endl << endl;
	}

	fin.close();
	cout.unsetf(ios::fixed | ios::showpoint);
	cin >> a;// Just to prevent screen from closing.
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#include <fstream>
#include <iomanip>
#include <iostream>
// #include <string>
// using namespace std;

#include <cmath>

int main()
{

  //variable for the degree symbol
  char degreeSymbol = 0xF8; // *** locale/platform-specific

  /*
  ifstream fin;
  fin.open("temps.txt");
  if (!fin.good()) throw "I/O error";
  */
  std::ifstream fin( "temps.txt" ) ; // constructor opens the file
  if( !fin.is_open() )
  {
      std::cerr << "could not open file for input\n" ;
      return 1 ;
  }

  // end of file loop to check for sentinel value of -999
  // while (fin.good())
  double celsius ;
  const double sentinel = -999 ;
  const double delta = 0.0001 ;
  // See: 'Why doesn’t my floating-point comparison work?' in http://isocpp.org/wiki/faq/newbie

  // idiomatic C++ input loop
  //     execute the loop's body only if the input operation succeeded
  //     and the input is not equal to the sentinel value
  while( fin >> celsius && ( std::abs(celsius-sentinel) > delta ) )
  {
    // read an int from one line of an input file
    // float a;
    // fin >> a;
    // fin.ignore(1000, 10);

    // sentinel value
    // if (a == -999) break;

    //programmer supplied formula for conversion
    // float b = 1.8 * a + 32;
    const double fahrenheit = 1.8 * celsius + 32 ;

    //unformatted output
    std::cout << celsius << degreeSymbol << " Celsius equals ";

    //formatting output to 1 decimal place
    std::cout.setf( std::ios::fixed|std::ios::showpoint);
    const int default_precision = std::cout.precision() ; // *** added
    std::cout << std::setprecision(1);

    //formatted output
    std::cout << fahrenheit << degreeSymbol << " Fahrenheit.\n\n" ; // << endl << endl;
    std::cout.unsetf(std::ios::fixed|std::ios::showpoint);
    std::cout << std::setprecision(default_precision); // *** added: restore default precision

  }

  // fin.close(); // destructor closes the file
}
Perfect! Line 56 and 62 of JLBorges post was what I needed. Now when I run it the inputs are unformatted and the outputs are formatted. Heres my updated code, which works the way I needed it to.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#include <fstream>
#include <iomanip>
#include <iostream>
#include <string>
using namespace std;

#include <cmath>

int main()
{
  //variable for the degree symbol
  char degreeSymbol = 0xF8;

  ifstream fin;
  fin.open("temps.txt");
  if (!fin.good()) throw "I/O error";


  // end of file loop to check for sentinel value of -999
  while (fin.good())
  {
    // read an int from one line of an input file
    double a;
    fin >> a;
    fin.ignore(1000, 10);

    // sentinel value
    if (a == -999) break;

    //programmer supplied formula for conversion
    double b = 1.8 * a + 32;

    //unformatted output
    cout << a << degreeSymbol << " Celsius equals ";

    //formatting output to 1 decimal place
    cout.setf(ios::fixed|ios::showpoint);
    int default_precision = cout.precision();
    cout << setprecision(1);

    //formatted output
    cout << b << degreeSymbol << " Fahrenheit." << endl << endl;
    cout.unsetf(ios::fixed|ios::showpoint);
    cout << setprecision(default_precision);
    cout.precision();
  }

  fin.close();

}



Now when I input
1
2
3
4
5
6
100
0
-40
100.001
-5.9
22


The output I get is

1
2
3
4
5
6
7
100 Celsius equals 212.0 Fahrenheit
0 Celsius equals 32. Fahrenheit
-40 Celsius equals -40.0 Fahrenheit
100.001 Celsius equals 212.0 Fahrenheit
-5.9 Celsius equals 21.4 Fahrenheit
22 Celsius equals 71.6 Fahrenheit
Topic archived. No new replies allowed.