-3

Working on a project where I need to fill a file with numbers and use a getline to read those numbers line by line and then display the total, average, max, and min from each line. Everything's in place except my getline doesn't seem to be working as the output for the total, average, etc, is always 0. Any help at all is appreciated. Thanks!

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

int main() {
    ofstream myfile;
    myfile.open("file.txt");
    if(!myfile)
    {
        cout << "Unable to open file\n";
        return 0;
    }
    if(myfile.is_open())
    {
        myfile << "Numbers: \n";
        myfile << "90 63 84 52 21 93 77 46\n";
        myfile << "90 22 26 34 39 44 75 98\n";
        myfile << "28 28 85 57 28 33 66 100\n";
        myfile << "16 80 74 62 42 84 42 56\n";
        myfile << "85 44 76 97 16 64 80 14\n";
        myfile << "41 85 13 88 78 8 18 38\n";
        myfile << "53 49 71 79 75 57 93 62\n";

        fstream infile;
        infile.open("file.txt");
        int total, average, max=0, min=0, num;
        while(!infile.eof())
        {
            string line;
            getline(infile, line);
            int a, b, c, d, e, f, g, h, i;
            infile >> a >> b >> c >> d >> e >> f >> g >> h >> i;
            total = a+b+c+d+e+f+g+h+i;
            average = total/7;
            while(infile>>num)
            {
                max = num;
                min = num;
                if(max<num)
                {
                    max = num;
                }
                if(min > num)
                {
                    min = num;
                }
            }
            myfile << "                               TOTAL        AVERAGE      MAX      MIN\n";
            myfile << "90 63 84 52 21 93 77 46    " << total << "  " << average << "  " << max << "  " << min << endl;
            myfile << "90 22 26 34 39 44 75 98\n";
            myfile << "28 28 85 57 28 33 66 100\n";
            myfile << "16 80 74 62 42 84 42 56\n";
            myfile << "85 44 76 97 16 64 80 14\n";
            myfile << "41 85 13 88 78 8 18 38\n";
            myfile << "53 49 71 79 75 57 93 62\n";
        }
        infile.close();
    }
    myfile.close();
    return 0;
}
Remy Lebeau
  • 454,445
  • 28
  • 366
  • 620
  • You're using `getline` to ignore that line... – LogicStuff Nov 15 '17 at 17:19
  • Sorry, could you elaborate? Super new to c++ here. I've tried looking this problem up and most code i've looked at uses getline like that. How should it look instead? – C the Destroyer Nov 15 '17 at 17:22
  • https://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-considered-wrong –  Nov 15 '17 at 17:27

2 Answers2

0

all sorts of funky things going on here

First opening a file for writing, then opening it for reading and writing to it while reading might work but looks odd. Better to write a new file out in the second phase

Second, you write 8 numbers , read 9 and divide total by 7 to get mean. Thats surely broken.

The style is odd, using a while loop and then inside that loop running out to end of file with another while loop. Is that really what you mean? That while on min and max will read the whole file

in your max and min, you should set min to a very large number, not 0. Other wise min>num will never be true

pm100
  • 32,399
  • 19
  • 69
  • 124
0

There are many problems with your code.

You are not closing myfile before opening infile (which should be a std::ifstream instead). While not strictly an error, it is unusual. If you are trying to modify the file while you are reading from it, that is not safe. Write to a new file first, and then replace the old file with the new file when finished, if needed.

You are not doing any error handling on infile at all.

You are misusing eof().

Your reading of infile is just WAY off and makes no sense at all. It needs to be completely re-written.

You are outputting 8 numbers per line, but you are reading in 9 numbers per line, and averaging 7 of them.

I think what you are trying to do is produce an output file where you display stats for each line of numbers. If so, try something more like this:

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

int main()
{
    ofstream myfile("numbers.txt");
    if (!myfile)
    {
        cout << "Unable to create numbers file\n";
        return 0;
    }

    myfile << "90 63 84 52 21 93 77 46\n";
    myfile << "90 22 26 34 39 44 75 98\n";
    myfile << "28 28 85 57 28 33 66 100\n";
    myfile << "16 80 74 62 42 84 42 56\n";
    myfile << "85 44 76 97 16 64 80 14\n";
    myfile << "41 85 13 88 78 8 18 38\n";
    myfile << "53 49 71 79 75 57 93 62\n";
    myfile.close();

    ifstream infile("numbers.txt");
    if (!infile)
    {
        cout << "Unable to open numbers file\n";
        return 0;
    }

    myfile.open("output.txt");
    if (!myfile)
    {
        cout << "Unable to create output file\n";
        return 0;
    }

    myfile << "Numbers:                       TOTAL        AVERAGE      MAX      MIN\n";

    string line;
    while (getline(infile, line))
    {
        istringstream iss(line);
        ostringstream oss;

        int num, total = 0, count = 0, average = 0, max = 0, min = 0;

        if (iss >> num)
        {
            max = min = num;

            do
            {
                total += num;
                ++count;

                if (num > max)
                    max = num;

                if (num < min)
                    min = num;

                oss << num << ' ';
            }
            while (iss >> num);

            average = total / count;
        }

        myfile << left << setw(30) << setfill(' ') << oss.str() << " ";
        myfile << left << setw(12) << setfill(' ') << total << " ";
        myfile << left << setw(12) << setfill(' ') << average << " ";
        myfile << left << setw(8) << setfill(' ') << max << " ";
        myfile << min << endl;
    }

    infile.close();
    myfile.close();

    return 0;
}

numbers.txt

90 63 84 52 21 93 77 46
90 22 26 34 39 44 75 98
28 28 85 57 28 33 66 100
16 80 74 62 42 84 42 56
85 44 76 97 16 64 80 14
41 85 13 88 78 8 18 38
53 49 71 79 75 57 93 62

output.txt

Numbers:                       TOTAL        AVERAGE      MAX      MIN
90 63 84 52 21 93 77 46        526          65           93       21
90 22 26 34 39 44 75 98        428          53           98       22
28 28 85 57 28 33 66 100       425          53           100      28
16 80 74 62 42 84 42 56        456          57           84       16
85 44 76 97 16 64 80 14        476          59           97       14
41 85 13 88 78 8 18 38         369          46           88       8
53 49 71 79 75 57 93 62        539          67           93       49

Alternatively, you can remove numbers.txt altogether if you use an in-memory array instead of a file:

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

const int numbers[7][8] = {
    {90, 63, 84, 52, 21, 93, 77, 46},
    {90, 22, 26, 34, 39, 44, 75, 98},
    {28, 28, 85, 57, 28, 33, 66, 100},
    {16, 80, 74, 62, 42, 84, 42, 56},
    {85, 44, 76, 97, 16, 64, 80, 14},
    {41, 85, 13, 88, 78, 8 , 18, 38},
    {53, 49, 71, 79, 75, 57, 93, 62}
};

int main()
{
    ofstream myfile("output.txt");
    if (!myfile)
    {
        cout << "Unable to create output file\n";
        return 0;
    }

    myfile << "Numbers:                       TOTAL        AVERAGE      MAX      MIN\n";

    for(int i = 0; i < 7; ++i)
    {
        int num = numbers[i][0];
        int total = num, max = num, min = num;

        ostringstream oss;
        oss << num << ' ';

        for(int j = 1; j < 8; ++j)
        {
            num = numbers[i][j];
            total += num;

            if (max < num)
                max = num;

            if (min > num)
                min = num;

            oss << num << ' ';
        }

        int average = total / 8;

        myfile << left << setw(30) << setfill(' ') << oss.str() << " ";
        myfile << left << setw(12) << setfill(' ') << total << " ";
        myfile << left << setw(12) << setfill(' ') << average << " ";
        myfile << left << setw(8) << setfill(' ') << max << " ";
        myfile << min << endl;
    }

    myfile.close();

    return 0;
}

output.txt

Numbers:                       TOTAL        AVERAGE      MAX      MIN
90 63 84 52 21 93 77 46        526          65           93       21
90 22 26 34 39 44 75 98        428          53           98       22
28 28 85 57 28 33 66 100       425          53           100      28
16 80 74 62 42 84 42 56        456          57           84       16
85 44 76 97 16 64 80 14        476          59           97       14
41 85 13 88 78 8 18 38         369          46           88       8
53 49 71 79 75 57 93 62        539          67           93       49
Remy Lebeau
  • 454,445
  • 28
  • 366
  • 620