user17094681
user17094681

Reputation: 1

Using sentinel values and counter control to get data from a file

I am trying to allow the user to select which file to open then use either a sentinel value or counter control to get all the values from the selected file. The code I have just outputs:

There are 0 values in the file.

The values in the file are: -1206517578

The average is -inf

Which is not true as there are 10 numbers in each file and they are all less than 9. I have been staring at this and can't figure out what is wrong.

#include <iostream>
#include <fstream>
#include <cstdlib>
using namespace std;

int main() {

    char fileSel;
    double numValues = 0; //# of values in list
    int values; //numbers in list
    double avg = values / numValues;
    int counter = 10;
    const int SENTINAL_VALUE = -9999;

//Which file would you like to open?
    cout << "Which file would you like to open?" << endl;
//1. Counter Controlled
    cout << "1. Counter Controlled" << endl;
//2. Sentinel Controlled
    cout << "2. Sentinel Controlled" << endl;
//Input file
    cin >> fileSel;

//loop file selected
//counter controlled
    while (fileSel == 1){
        //open and check file
        ifstream inFile;
        inFile.open("counter_controlled.txt ");

        if (inFile.fail()) {
            cerr << "Could not open input file" << endl;
            return -1;
        }
        while (numValues <= counter) {
            inFile >> values;
            numValues += 1;
        }

        inFile.close();
    }



    //sentinal
    while ( fileSel == 2) {
        //open and check file
        ifstream inFile;
        inFile.open("sentinel_controlled.txt");

        if (inFile.fail()) {
            cerr << "Could not open input file" << endl;
            return -1;
        }

        //get values until
        while (inFile >> values);
        numValues += 1;
        if (values == SENTINAL_VALUE){
            cout << "There are " << numValues << " values in the file." << endl;
            cout << "The values in the file are: " << values << endl;
            //The average is 4.93.
            cout << "The average is " << avg << endl;
        }
        inFile.close();
    }

    //The values in the file are:
    cout << "There are " << numValues << " values in the file." << endl;
    cout << "The values in the file are: " << values << endl;
    cout << "The average is " << avg << endl;

    return 0;
}

Upvotes: 0

Views: 441

Answers (2)

JDługosz
JDługosz

Reputation: 5652

In addition to dirck's observation that you are computing the results before you have the data, there is much more wrong with it.

You are reading the same value over and over, not making a collection of values and not summing the values read.

while (inFile >> values);
has nothing to do with stopping at the sentinel, and the following block of code will test the last value read (only), which is the last value in the file.

Upvotes: 0

dirck
dirck

Reputation: 868

Starting with just these 3 lines of code:

    double numValues = 0; //# of values in list
    int values; //numbers in list
    double avg = values / numValues;

at this point avg is UNINITIALIZED divided by ZERO, which is not good in multiple ways. I'd think the compiler would have a lot to say about this.

values actually has to be accumulated before its average can be calculated, and values is never accumulated into anything, you just read it in over and over.

...C++ is imperative, not declarative like Excel.

Upvotes: 1

Related Questions