-1

I am new to programming and trying to teach myself but my counter is displaying one more than it should. it should be displaying 22, but it is displaying 23.

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

//Main and variable data type initializing

void main()
{    float c,l,x,y,z;
    int count;
    string input, output;
    string finput, foutput;
    fstream i,o;    //i = input file;    o = output file;
//Getting the name of the files

    cout << "XZY Multiply Program\n" << endl;
    cout << "Enter the input file name:  c:/";
    cin >> input;
    cout << "Enter the output file name:  c:/";
    cin >> output;

//inserts the beginning of the file and file extension.

    finput = "c:/" + input;
    foutput = "c:/" + output;

//Opens files

    i.open(finput.data(),ios::in);
    o.open(foutput.data(),ios::out);

//Initialize count and sum of variables

    count = 0;
    x=0;
    y=0;
    z=0;

//loop through input file

    while(!i.eof() && !o.eof())
    {   count++;
        if (i.good() && o.good())
        {

                i >> c;
                i >> l;   
                o << fixed << showpoint << setprecision(4);
                o << setw(7) << c;
                o << setprecision(2);
                o << setw(9) << l;
                o << setprecision(3);
                o << setw(10) << (l*c) << endl;

// Adds columns
                x = x+c;
                y = y+l;
               z = z+(l*c);

        } 
         else
        {
        cout << "no good";
        }

    }
     i.close();
     o.close();



    //Display the output of the counter and Sums of columns
            cout << fixed << showpoint << setprecision(2);
            cout << "\n" << count << " lines in file " << endl;
            cout << "X sum = " << setw(8) << right << x << endl;
            cout << "Y sum = " << setw(8) << right << y << endl;
            cout << "Z sum = " << setw(8) << right << z << endl;


}

  7.2830     84.40
  9.1327    124.02
  7.2619    133.16
  6.2527     43.96
  4.2160     24.08
  5.2724     57.80
  5.2025     73.89
 -9.9500     80.53
  0.2790    -12.43
  2.2115      3.37
  3.1222     13.63
 16.2413    223.01
 -4.2026     33.78
 -7.1914     42.89
  4.1417     53.42
  6.1714     61.66
  9.2516     73.68
 15.2419    383.66
  6.2715     93.53
 -3.2016      3.46
 12.2013    213.63
  3.1824     23.85
Oliver Charlesworth
  • 267,707
  • 33
  • 569
  • 680
MIkey27
  • 25
  • 1
  • 5
  • What did you discover when you debugged this? – Oliver Charlesworth Apr 12 '12 at 12:43
  • 4
    `while (!i.eof())` is a bug: http://www.parashift.com/c++-faq-lite/input-output.html#faq-15.5 – jrok Apr 12 '12 at 12:47
  • It's not a bug, it's just the way it works. There may be a carriage-return/line-feed on the last line so it's not really the last line. – Steve Wellens Apr 12 '12 at 13:14
  • @SteveWellens: There _should_ be a CR/LF on the last line since that's how text files are defined. CR/LF are terminators, not separators. – MSalters Apr 12 '12 at 13:30
  • possible duplicate of [Reading from text file until EOF repeats last line](http://stackoverflow.com/questions/21647/reading-from-text-file-until-eof-repeats-last-line) – Bo Persson Apr 12 '12 at 13:33
  • @MSalters - Nope. You can easily make a text file without an extraneous CRLF. Open notepad, type 'ABC' (do NOT press the Enter key) and save it. You can verify this by looking at the file with a hex editor. I was only pointing out that the situation needs to be dealt with. – Steve Wellens Apr 12 '12 at 15:10

2 Answers2

4

Using .eof() or .good() as a loop condition almost always produces buggy code, as it does in this case.

Rather, perform the input and check its result in the loop condition, like so:

while(i >> c >> l)
{   count++;
    o << fixed << showpoint << setprecision(4);
    o << setw(7) << c;
    ...

References:

Community
  • 1
  • 1
Robᵩ
  • 163,533
  • 20
  • 239
  • 308
0

I assume that after reading the last number from the input file the end of file has not been seen, yet. Try adding

if (!i.good()) break; 

after each input statement (>>) to prevent the loop body to be executed after a failed input.

ktf
  • 6,865
  • 1
  • 13
  • 6