Ian
Ian

Reputation: 1

C++ 2d array filling all elements with last element value in file

So this is my program that i have written. For some reason, it fills all of the elements of the array with the last elements value. The program is supposed to just open and read the file. Sum the rows. sum the columns then some the total of all of the elements.

#include <iostream>
#include <iomanip>
#include <fstream>
using namespace std;
const int NUM_TYPE = 5; // num of types of salsa
const int NUM_SALE = 4; // num of quarters per salsa

void salsaIn(float salsa[][NUM_SALE]);
void salsaType(float salsa[][NUM_SALE], int NUM_TYPE, int NUM_SALE);
void salsaQ(float salsa[][NUM_SALE], int NUM_TYPE, int NUM_SALE);
void totalSalsa(float salsa[][NUM_SALE], int NUM_TYPE, int NUM_SALE);
void displayArray(float salsa[][NUM_SALE], int NUM_TYPE, int NUM_SALE);

int main()
{
    float salsa[NUM_TYPE][NUM_SALE];

    salsaIn(salsa);
    displayArray(salsa, NUM_TYPE, NUM_SALE);
    salsaType(salsa, NUM_TYPE, NUM_SALE);
    salsaQ(salsa, NUM_TYPE, NUM_SALE);
    totalSalsa(salsa, NUM_TYPE, NUM_SALE);

    return 0;
}
//reads the salsa.txt file
void salsaIn(float salsa[][NUM_SALE])
{
    float salsaT = 0;
    ifstream file("salsa.txt");

    if (file.is_open())
    {
        cout << "Successful. Reading data." << endl;
        while (!file.eof())
        {
            for (int i = 0; i < NUM_TYPE; i++)
            {
                for (int j = 0; j < NUM_SALE; j++)
                {

                    file >> salsaT;
                    if (salsa < 0)
                    {
                        cout << "error, value less than 0, set to 0"<<endl;
                        salsaT = 0;
                    }

                    salsa[i][j] = salsaT;
                }
            }
        }

    }
    file.close();

    return;
}
//calculates and displays sales for each salsa type
void salsaType(float salsa[][NUM_SALE], int NUM_TYPE, int NUM_SALE)
{
    for (int row = 0; row < NUM_TYPE; row++)
    {
        float total = 0;

        for (int col = 0; col < NUM_SALE; col++)
        {
            total += salsa[row][col];
        }
        //display the total sales for each salsa type.
        cout << "total sales for salsa " << (row + 1) << " is " << total
                << endl;

        return;
    }

}
void displayArray(float salsa[][NUM_SALE], int NUM_TYPE, int NUM_SALE)
{
    for (int row = 0; row < NUM_TYPE; row++)
    {
        float total = 0;

        for (int col = 0; col < NUM_SALE; col++)
        {
            cout << setw(5) << salsa[row][col] << endl;
        }
        //display the total sales for each salsa type.
    }

    return;
}
//calculates and displays the sales of each quarter.
void salsaQ(float salsa[][NUM_SALE], int NUM_TYPE, int NUM_SALE)
{
    for (int col = 0; col < NUM_SALE; col++)
    {
        float totalq = 0;

        for (int row = 0; row < NUM_TYPE; row++)
            totalq += salsa[row][col];

        cout << "Sales for quarter " << (col + 1) << " is " << totalq << endl;
    }

    return;

}
//calculates and displays the sales for the company last year.
void totalSalsa(float salsa[][NUM_SALE], int NUM_TYPE, int NUM_SALE)
{
    float totalS = 0;
    for (int row = 0; row < NUM_TYPE; row++)
    {

        for (int col = 0; col < NUM_SALE; col++)

            totalS += salsa[row][col];

    }

    cout << "The total sales for the company last year is " << totalS << endl;
}

This is the final output of the program.

Successful. Reading data.
3905.64
3905.64
3905.64
3905.64
3905.64
3905.64
3905.64
3905.64
3905.64
3905.64
3905.64
3905.64
3905.64
3905.64
3905.64
3905.64
3905.64
3905.64
3905.64
3905.64
total sales for salsa 1 is 15622.6
Sales for quarter 1 is 19528.2
Sales for quarter 2 is 19528.2
Sales for quarter 3 is 19528.2
Sales for quarter 4 is 19528.2
The total sales for the company last year is 78112.8

Thanks for the help guys. I'm kinda of stuck on the rest of the program.

Upvotes: 0

Views: 275

Answers (1)

user4581301
user4581301

Reputation: 33952

What's going on:

while (!file.eof())

Loop until the EOF flag is set. This flag will not be set until the program tries to read a value from the file and finds the end of the file. Often this means the EOF flag is not set until the program attempts to read a value from the file and fails because there are no more values to be read.

{
    for (int i = 0; i < NUM_TYPE; i++)
    {
        for (int j = 0; j < NUM_SALE; j++)
        {

These loops will attempt to read 20 values from the file

            file >> salsaT;

Read a value from the file. There is no check to ensure a value was read from the file. When this fails, the value in salsaT BEFORE C++11 is unchanged. After C++11 it's zeroed. If you're not compiling for C++11, there's your repeated last number.

            if (salsa < 0) // unrelated bug here
            {
                cout << "error, value less than 0, set to 0"<<endl;
                salsaT = 0;
            }

            salsa[i][j] = salsaT;
        }
    }
}

20 values are read from the file or each iteration of the while (!file.eof()) loop. If there are exactly 20 values in the file, all 20 are read. The EOF may not be set, so the while loop is entered. Another 20 values are read into the same array, but this time there are no values to be read. It's very likely that the array is packed with 20 repeats of the last value successfully read.

Solution:

Death to the while loop!

for (int i = 0; i < NUM_TYPE; i++)
{
    for (int j = 0; j < NUM_SALE; j++)
    { // read 20 values from file
        if (file >> salsaT)
        { // if we got a value
            if (salsaT < 0)
            {
                cout << "error, value less than 0, set to 0"<<endl;
                salsaT = 0;
            }
        }
        else
        { // Bad or no value. try to clean up.
            if (file.eof())
            {
                cout << "File ended too soon"<<endl;
            }
            else
            {
                cout << "error, bad value in file"<<endl;
                file.clear();
                file.ignore(numeric_limits<streamsize>::max(), '\n');
            }
            salsaT = 0;
        }
        salsa[i][j] = salsaT; // store
    }
}

Upvotes: 1

Related Questions