While loop when opening a file

Please help me figure out where my while loop is not functioning correctly.
The goal is to read numbers in a input file and tell what percent of the numbers are positive, negative, and zeros.
When i wrote the code int he main function it worked correctly, but when i moved it into a function and tried to pass by reference, somewhere the zero an total are giving me bogus numbers.



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
#include <iostream>
#include <fstream>
#include <iomanip>

using namespace std;

void openInputFile(double &neg, double &pos, double &zero, double &total);

int main()
{
   double neg, pos, zero, total;
   openInputFile(neg, pos, zero, total);

       cout << "Neg is " << neg << endl;
       cout << "Pos is " << pos << endl;
       cout << "Zero is " << zero << endl;
       cout << "Total is " << total << endl;

       //cout << fixed << setprecision(2) << "The percent of numbers that were negative are " << (neg/total) * 100 << "%" << endl;
      // cout << fixed << setprecision(2) << "The percent of numbers that were positive are " << (pos/total) * 100 << "%" << endl;
       //cout << fixed << setprecision(2) << "The percent of numbers that were zero are " << (zero/total) *  100 << "%" << endl;

   return 0;
}

void openInputFile(double &neg, double &pos, double &zero, double &total)
{
    const string NAME = "numbers.txt";
    ifstream testFile;

    double num;

    testFile.open(NAME);

    if (!testFile.fail())
    {
       cout << "The file opened" << endl;
       while (testFile >> num)
       {
          total++;

          if (num < 0)
          {
             neg++;
          }
          else if (num > 0)
          {
             pos++;
          }
          else if (num == 0)
          {
             zero++;
          }
       }
    }
}


the input numbers are
10
-4
0
34
42
-2
0
0
5
7
8
1234
-33
-29837
12

my output looks like this
The file opened
Neg is 4
Pos is 8
Zero is 3.46332e+256
Total is -6.864e+072

Process returned 0 (0x0)   execution time : 0.016 s
Press any key to continue.
Last edited on
Hi,

Initialise all of your variables to something :+) It's a golden rule
It was as simple as that? can you explain why pos and neg didn't have the invalid value like zero and total?
May be you were lucky, they happened to have values of zero to start with. That is the nature of Undefined Behaviour.

Also be careful with equality comparisons with doubles. It works for whole numbers up to 32 bit in size, but probably not otherwise.

One can write a function that tests equality within a precision value. See if the absolute value of the difference between the 2 numbers is less than the precision value.

You should also print something if the file is not opened, and if the read operation fails.

There is also a problem with line 40, you should be able to figure that out yourself :+)

Good Luck !!
Last edited on
I rewrote the code.

I fixed the zero comparison to just be a trailing else and added a error message if the file does not open.

I couldn't figure out what was wrong with line 40 but the whole program runs correctly now.

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
68
69
70
// Lab 9b Exercise 2
#include <iostream>
#include <fstream>
#include <iomanip>
#include <cstdlib>


using namespace std;

void openInputFile(double &neg, double &pos, double &zero, double &total);
void negPrecentage(double neg, double total);
void posPrecentage(double pos, double total);
void zeroPrecentage(double zero, double total);


int main()
{
   double neg = 0, pos = 0, zero = 0, total = 0 ;
   openInputFile(neg, pos, zero, total);

       negPrecentage(neg, total);
       posPrecentage(pos, total);
       zeroPrecentage(zero, total);

   return 0;
}

void openInputFile(double &neg, double &pos, double &zero, double &total)
{
    const string NAME = "numbers.txt";
    ifstream testFile;

    double num;

    testFile.open(NAME);

    if (!testFile.fail())
    {
       while (testFile >> num)
       {
          total++;
          if (num < 0)
          neg++;
          else if (num > 0)
          pos++;
          else
          zero++;
       }
    }
    else
    {
       cout << "File open failed " << endl;
       exit(0);
    }

}

void negPrecentage(double neg, double total)
{
   cout << fixed << setprecision(2) << "The percent of numbers that were negative are " << (neg/total) * 100 << "%" << endl;
}

void posPrecentage(double pos, double total)
{
   cout << fixed << setprecision(2) << "The percent of numbers that were positive are " << (pos/total) * 100 << "%" << endl;
}
void zeroPrecentage(double zero, double total)
{
   cout << fixed << setprecision(2) << "The percent of numbers that were zero are " << (zero/total) * 100 << "%" << endl;
}


Last edited on
I couldn't figure out what was wrong with line 40 but the whole program runs correctly now.


Is it really a total? Or a count? It works, but is confusing :+|

Avoid declaring multiple variables on 1 line, and I always like to put digits before and after floating point numbers - it helps with some tricky to diagnose problems:

1
2
3
4
double neg = 0.0;
double pos = 0.0;
double  zero = 0.0;
double  total = 0.0 ;


There is no need to have cout statements as 1 giant line of code:

1
2
3
4
5
6
void negPrecentage(double neg, double total)
{
   cout << fixed << setprecision(2) 
           << "The percent of numbers that were negative are " 
           << (neg/total) * 100 << "%" << endl;
}


Perhaps it is not too bad here, but often people make them too long.

Thanks, i corrected the syntax there. Do you just make the cout statements smaller for easier debugging and making it easier to read?
Just to make it easier to read :+) It's an important concept.

Another thing, use const where ever you can:

1
2
3
4
5
6
7
void negPrecentage(const double neg,  // multi-line format for multiple parameters
                   const double total)         // is easier to read too
{
   cout << fixed << setprecision(2) 
           << "The percent of numbers that were negative are " 
           << (neg/total) * 100.0 << "%" << endl; // FP numbers with digits either side of dp
}

Last edited on
Topic archived. No new replies allowed.