0

I have started working on a program, and for the life of me I can't find a bug which continuously searches the eof and doesn't end. It is most certainly a problem with my fileread and widthcount functions, and they most likely have the same error. Is there a fix for this? It just keeps looping.

The file input is this

12.43 62.38 Los Angeles
21 59 Columbus, Ohio
0 15.58 Green Bay, Wisconsin

This continues for another 10 lines.

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

void fileread(ifstream &ifFile, char newline, double &temp1, double &temp2, string city);
void widthcount(ifstream &ifFile, int &maxCount, char newline);

int main() {
   double temp1, temp2, minTemp, maxTemp;
   int maxCount;
   char newline=' ';
   string FileRead, city;
   ifstream ifFile;

   cout << "Please enter the location of the input file: ";
   cin >> FileRead;

   ifFile.open(FileRead.c_str());

   if (ifFile.fail()) {
       perror(FileRead.c_str());
       exit(1);
   }

   widthcount(ifFile, maxCount, newline);

   while(!ifFile.eof()) {
       widthcount(ifFile, maxCount, newline);
   }      

   ifFile.close();

   ifFile.open(FileRead.c_str());

   fileread(ifFile, newline, temp1, temp2, city);

   while(!ifFile.eof()) {
       fileread(ifFile, newline, temp1, temp2, city);

       cout << left << setw(20) << city
             << right << setw(6) << fixed << setprecision(2) << temp1
             << right << setw(6) << fixed << setprecision(2) << temp2 << endl;

   }

}

void fileread(ifstream &ifFile, char newline, double &temp1, double &temp2, string city) {
   int charcount = 0;

   ifFile >> temp1 >> temp2;

   while (newline == ' ')
       ifFile.get(newline);
   while (newline != '\n' || !ifFile.eof()) {
       charcount++;
       ifFile.get(newline);
   }
}

void widthcount (ifstream &ifFile, int &maxCount, char newline) {
   double temp1, temp2;
   int charcount = 0;
   ifFile >> temp1 >> temp2;
   ifFile.get(newline);
   while (newline != '\n' && !ifFile.eof()) {
       charcount++;
       ifFile.get(newline);
       cout << newline;
   }

   if (charcount > maxCount)
    maxCount = charcount;
}
Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
Josh Ferrell
  • 89
  • 1
  • 3
  • 12
  • What happens if you don't run the "widthcount" part of this, and just set maxCount to something reasonable? – Xymostech Oct 26 '12 at 02:19
  • 2
    `eof()` is always wrong. And it's always an error to discard the result of an input operation. – Kerrek SB Oct 26 '12 at 02:22
  • @xymostech not running widthcount will continue to fileread in which it will just loop forever after it has read the file there. – Josh Ferrell Oct 26 '12 at 02:25
  • @KerrekSB Is there another method that you suggest? – Josh Ferrell Oct 26 '12 at 02:26
  • @JoshFerrell: This has a million duplicates here on SO. Search around a bit, I'm sure you'll find something useful. – Kerrek SB Oct 26 '12 at 02:32
  • @JoshFerrell I usually check against good(), since that returns false on the event of an error, fail or eof. So anything that would (and should) stop you from reading come end of file, or some other issue. – M4rc Oct 26 '12 at 02:32

3 Answers3

3

You need to check for failure (test .fail()), not end of file.

Typically .fail() is checked by using the stream object directly as condition.

E.g. while( f ) is equivalent to while( !f.fail() ).

Cheers and hth. - Alf
  • 142,714
  • 15
  • 209
  • 331
  • This solution works, but it doesn't when it comes to the loop located here with widthcount. I tried doing an if statement checking to see if the fail failed, if it failed then it would output "test" this worked. However, if I tried to break the loop or made the loop be false in any way, it would just continue looping and wouldn't do anything else. – Josh Ferrell Oct 26 '12 at 03:45
  • Take this back, I got it to work. Thank you so much for this solution. Don't know why our teacher told us to use eof if there are so many problems with it. Have an internet hug. – Josh Ferrell Oct 26 '12 at 03:51
0

Checking specifically for eof() is almost always a mistake -- for example, if you encounter some other error before reaching the end of the file, eof will remain false, but reading will fail (but since eof remains false, your loop will continue attempting to read and failing, forever).

Personally, I'd structure the code quite a bit differently. I'd start by creating a struct to represent one "record" from the file:

struct city {
    double temp1, temp2; // horrible names, but I don't know what they represent.
    std::string name;
};

Then I'd overload operator>> to extract the data for one city from a stream, and operator<< to display the data for a city:

std::istream &operator>>(std::istream &is, city &c) { 
    is >> c.temp1 >> c.temp2;
    std::getline(is, c.name);
    return is;
}

std::ostream &operator<<(std::ostream &os, city const &c) { 
    return cout << left << setw(20) << c.name
                << right << setw(6) << fixed << setprecision(2) << c.temp1
                << right << setw(6) << fixed << setprecision(2) << c.temp2;
}

Then I'd use those to read and write the data as god intended (with an algorithm):

int main(int argc, char **argv) {

    // For the moment, cheat and take the file name from the command line
    std::ifstream ifFile(argv[1]);

    std::copy(std::istream_iterator<city>(ifFile),
              std::istream_iterator<city>(),
              std::ostream_iterator<city>(std::cout, "\n"));
    return 0;
}

As an aside, I'd note that although you call widthcount, you never seem to use any result from it. At least for now, I've skipped over doing anything similar, since it didn't affect the result.

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
0

You should try something like

double t1,t2;
string s1,s2;

ifstream ifs;
ifs.open(Filename.c_str());

ifs>>t1>>t2>>s1>>s2;

while(ifs)
{
.......
do the calculations
.......
ifs>>t1>>t2>>s1>>s2;
}

This works for all the cases.If ,after the first read,ifs enters the fail state then rest of the file reading will be skipped and lines after the while loop will be executed.Other wise, rest of the lines will be read in the loop.You can change your requirement based on whether you want to read a string,a character or a line.

Recker
  • 1,915
  • 25
  • 55