I am unable to figure out how to check to see if there is more data in the file. I have a input file, where the last two lines are just new lines with new data. When I run my code, I get the last line of data in the file sent through the program twice. I will first put in my code, then followed by the input from the file. I want to know how, to see if there is actually more data or just empty lines.

#include <iostream>
#include <cmath>            // able to use math functions
#include <fstream>          // able to send and recieve data from files

using namespace std;

ofstream outfile;       // declarition of in and out files
ifstream infile;

void lines(int &line1, int &line2, int &line3);  // prototypes
char valid(int line1, int line2, int line3);
char right(int line1, int line2, int line3);
void output(int a, int b, int c, char x, char y);

int main()
{
     outfile.open("triangleout.out");  //open outfile
     if (!outfile)                // check outfile is open
     {
         outfile << "Output file did not open.\n";
         return 1;
     }
     infile.open("triangle2.txt");  // open infile
     if (!infile)                    // check infile is open
     {
         outfile << "Input file did not open.\n\n";
         return 1;
     }

     int line1, line2, line3;        // variables for lines
     char r_tri, val_tri;            // and calculation

     while (!infile.eof())       // loops until all data in the file is
     {                   // used, eof() is End Of File
                         // the infile is the name of the file declared
                         // the '!' means NOT, so do this while we are NOT
                         // at the end of file
         lines(line1, line2, line3);
         val_tri = valid(line1, line2, line3);   // function calls
         r_tri = right(line1, line2, line3);

         output(line1, line2, line3, val_tri, r_tri);

         outfile << "\n\n";
     };

     infile.close();        // close the infile
     outfile.close();       // close the outfile

     return 0;
}

void lines(int &line1, int &line2, int &line3)
{
     infile >> line1 >> line2 >> line3;  // brings data in from outside
                                         // file, also there is no user
                                         // input
}

char valid(int line1, int line2, int line3)
{
     char x;

     if ((line1 + line2) >= line3 && (line2 + line3) >= line1 && (line1
+ line3) >= line2)
     {
         x = 'Y';            // this checks to make sure all three
     }                       // possible variations of the calculation
     else
     {
         x = 'N';
     }
     if ((line1==0||line2==0||line3==0))
     {
         x = 'N';
     }
     return x;       // returns a char value of Y or N
}

char right(int line1, int line2, int line3)
{
     char y;         // declare variables for right angle calculation
     int check1, check2, big_check, big;

     if (line1 > line2)          // 2 big if statements to check which
     {                           // side is the biggest
         check1 = pow(line2,2);

         if (line1 > line3)
         {
             big_check = pow(line1,2); // check calculations raise the
             check2 = pow(line3,2);      // desired variables to the
         }                               // power of 2
         else
         {
             big_check = pow(line3,2);
             check2 = pow(line1,2);
         }
     }
     else
     {
         check1 = pow(line1,2);

         if (line2 > line3)
         {
             big_check = pow(line2,2);
             check2 = pow(line3,2);
         }
         else
         {
             big_check = pow(line3,2);
             check2 = pow(line2,2);
         }
     }

     if (big_check == check1 + check2)
     {                   // this checks thats the biggest side squared is
         y = 'Y';        // equal to the two smaller sides squared
     }
     else
     {
         y = 'N';
     }

     return y;
}

void output(int a, int b, int c, char x, char y)
{
     outfile << "A triangle with 3 sides, at " << a << ", " << b;
     outfile << ", " << c << ", is ";
                                             // outputs everything

     if (x == 'Y')
     {
         outfile << "a valid trinalge.";

         if (y == 'Y')
         {
             outfile << " Also, this is a right triangle.";
         }
         else
         {
             outfile << "However, it is not a right triangle.";
         }
     }
     else
     {
         outfile <<"not a valid triangle and hence not a right triangle.";
     }
}

Now here is the input file(exactly):


10 8 4
4 8 10
90 200 125
5 12 6
90 181 90
1588 2300 4000
90 90 180
5 25 45
6000 7500 7000
1 1 1
1000 1 1000
50 20 5
1 1000 2500
0 0 0
(empty line, just so you understand)
(empty line)

Please help. I am new to programming, so go easy.

It's temping to use the stream extraction operator, >> , to read from files, but I almost never find it to be a good idea, for reasons like you're finding.

The most robust way to read this kind of data is to use getline , see the example here. This way you can get a line from the file and discard it if it has zero length (or, more correctly, if it's empty). The downside to this is that you have to split the line into individual tokens manually. For your data, this isn't too hard. If you read the line into a std::string then you can use a std::stringstream to process the data in a similar way to the way you're currently doing it. Here's a simple example that does this:

#include <iostream>
#include <sstream>
#include <string>
#include <fstream>
#include <vector>
#include <algorithm>
#include <iterator>

struct LineData
{
    int x;
    int y;
    int z;

    friend std::ostream& operator<<( std::ostream& right, const LineData& data )
    {
        right << "(" << data.x << ", " << data.y << ", " << data.z << ")";
        return right;
    }
};

int main()
{
    std::ifstream file( "test.txt", std::ios::in );
    if ( ! file.is_open() )
        return 1;

    std::vector< LineData > vLineData;

    while ( ! file.fail() )
    {
        std::string lineFromFile;
        getline( file, lineFromFile );      // Get a line from the file and store it in a string

        if ( lineFromFile.empty() )
            continue;       // Skip blank lines

        std::stringstream ss( lineFromFile );   // Make a stringstream from the line from the file
        LineData temp;
        ss >> temp.x >> temp.y >> temp.z;       // Extract the tokens on the line from the string

        if ( ! ss.fail() )    // Don't add lines that didn't read properly
            vLineData.push_back( temp );
    }

    // Print out all the line data that we read, to check that we got all the lines properly
    std::copy( vLineData.begin(), vLineData.end(), std::ostream_iterator< LineData >( std::cout, "\n" ) );

    return 0;
}

Edited 4 Years Ago by ravenous: punctuation

This article has been dead for over six months. Start a new discussion instead.