EDIT: originally I thought that this was due to the different IDE's I tested the program on. The problem seems to be narrowed down to the separate compilers that each IDE uses.
For an assignment in my introduction to C++ class, I needed to write a program that reads doubles from a file, and evaluates them, the outputs the contents to another .txt file
I wrote the program using Visual Studio 2012, and it reads the file as I would expect, and executes as expected
I believe my teacher uses Dev C++ so I compiled the same code in that IDE as well as Code::Blocks.
What I have noticed is that the get pointer behaves differently, and I believe this is due to the compiler. In Code::Blocks and Dev C++, after the first double (6.0) is read, inFile.tellg() returns 15. In VS2012, it returns 3.
What could I do to this program so that it will work in all IDE's?
The file to be read:
The first 3 numbers of each line are dimensions of a box, the next 2 are the diameter and height of a jar to fit in the box.
6.0 6.0 10.3 5.0 10.0
6.0 5.0 10.3 5.0 10.0
12.0 3.3 4.0 3.0 11.0
12.0 3.2 4.0 3.0 11.0
9.5 6.5 7.5 6.0 9.5
9.5 6.5 7.5 6.0 9.0
4.5 8.0 4.5 4.0 7.5
4.0 8.0 4.5 4.0 7.5
7.3 7.3 17.0 7.0 16.0
6.8 7.3 17.0 7.0 16.0
7.3 7.3 16.2 7.0 16.0
7.2 7.3 16.3 7.0 16.0
The expected output (Executed in VS2012):
BOX JAR
L W H D H FITS?
===========================================================
6.0 6.0 10.3 5.0 10.0 YES
6.0 5.0 10.3 5.0 10.0 NO
12.0 3.3 4.0 3.0 11.0 YES
12.0 3.2 4.0 3.0 11.0 NO
9.5 6.5 7.5 6.0 9.5 NO
9.5 6.5 7.5 6.0 9.0 YES
4.5 8.0 4.5 4.0 7.5 YES
4.0 8.0 4.5 4.0 7.5 NO
7.3 7.3 17.0 7.0 16.0 YES
6.8 7.3 17.0 7.0 16.0 NO
7.3 7.3 16.2 7.0 16.0 NO
7.2 7.3 16.3 7.0 16.0 NO
===========================================================
The Output from Code::Blocks and Dev C++:
BOX JAR
L W H D H FITS?
===========================================================
6.0 6.0 10.3 5.0 10.0 YES
0.3 5.0 10.0 12.0 3.3 NO
1.0 12.0 3.2 4.0 3.0 NO
5.0 6.5 7.5 6.0 9.5 NO
5.0 7.5 6.0 9.0 4.5 NO
0.5 4.0 7.5 4.0 8.0 NO
4.0 7.5 7.3 7.3 17.0 NO
16.0 6.8 7.3 17.0 7.0 NO
0.0 7.3 7.3 16.2 7.0 NO
6.0 7.2 7.3 16.3 7.0 NO
16.0 16.0 16.0 16.6 7.2 NO
===========================================================
And finally the program:
#include <cstdlib>
#include <iostream>
#include <iomanip>
#include <fstream>
using namespace std;
bool hasDouble(ifstream&); // prototype
int main()
{
// initialize constants
// MAX_BOX_LENGTH must be modified to evaluate boxes with one or more sides >= 100.
const double ACCEPTABLE_CLEARANCE = 0.25, MAX_BOX_LENGTH = 100;
const int WID = 9;
// initialize variables
ifstream inFile;
ofstream outFile;
bool data_In_File = true;
bool jar_Fits = false;
double large_Box_Dim = 0, small_Box_Dim = 0, jar_D = 0, jar_H = 0, focus = 0;
// Welcome User to Program
cout << "Welcome to the \"Jar Fit?\" utility.\n\n\nThis program will open the \"P4Boxes.txt\" file"
<< " located in the same\ndirectory, and read the data from within it. The program will "
<< "then\ndetermine if the jar provided will fit in the box provided, with\nthe allowed "
<< "clearance. This data will be entered into the file\n\"NCBoxesOutput.txt\" in the same "
<< "directory.\n" << endl;
system("PAUSE");
inFile.open("P4Boxes.txt"); // Open input file
// Check for errors opening file by looking for a double
if(!hasDouble(inFile))
{
cout << endl << "There was an error opening the file.\n\nThe program will now terminate."
<< endl;
system("PAUSE");
return 1;
}
outFile.open("NCBoxesOutput.txt"); // Open output file
// Make output file header
outFile << setprecision(1) << fixed << showpoint << boolalpha << setw(WID * 2) << "BOX"
<< setw((WID * 4) + 1) << "JAR\n" << setw(WID) << "L " << setw(WID) << "W " << setw(WID)
<< "H " << setw(WID * 2) << "D " << setw(WID) << "H " << setw(WID) << "FITS?" << "\n"
<< setfill('=') << setw(WID * 7) << left << " " << right << setfill(' ') << endl;
// Main program loop
while(data_In_File)
{
jar_Fits = false; // Reset variables for each iteration
large_Box_Dim = 0;
small_Box_Dim = MAX_BOX_LENGTH;
for(int i = 0; i < 3; i++) // Get box dimensions.
{
inFile >> focus;
cout << "The read number is " << focus << " and the pointer is at " << inFile.tellg() << endl;
system("PAUSE");
if(focus > large_Box_Dim)
large_Box_Dim = focus; // For jar height comparison
if(focus < small_Box_Dim)
small_Box_Dim = focus; // For jar width comparison
outFile << setw(WID) << focus;
}
inFile >> jar_D >> jar_H; // Get jar Dimensions
outFile << setw(WID * 2) << jar_D << setw(WID) << jar_H;
jar_D += ACCEPTABLE_CLEARANCE; // Account for needed clearance
jar_H += ACCEPTABLE_CLEARANCE;
if((jar_D <= small_Box_Dim) && (jar_H <= large_Box_Dim)) // Does jar fit?
outFile << setw(WID) << "YES\n" << endl;
else
outFile << setw(WID) << "NO\n" << endl;
data_In_File = hasDouble(inFile); // is there another double in file?
}
outFile << setfill('=') << setw(WID * 7) << left << " " << right << setfill(' ') << endl;
cout << "\nThe program has executed successfully.\n" << endl; // Inform user
system("PAUSE");
return 0;
}
bool hasDouble(ifstream& inFile) // This function checks the file for for a double
{
double test = 0;
int place = 0;
place = inFile.tellg(); //This records the location of the get pointer
if(inFile >> test)
{
inFile.seekg(place); // If a double is found, the point is returned to previous location.
return true;
}
else
return false;
}
I apologize for the code dump, but I have been looking and cannot find a solid explanation for this or for how to fix it.
While I appriciate everyone's help in finding what the source of the issue was, my teacher was able to provide a solution to the problem.
Original Code:
bool hasDouble(ifstream& inFile) // This function checks the file for for a double
{
double test = 0;
int place = 0;
place = inFile.tellg(); //This records the location of the get pointer
if(inFile >> test)
{
inFile.seekg(place); // If a double is found, the point is returned to previous location.
return true;
}
else
return false;
}
Replacement code:
bool hasDouble(ifstream& inFile) // This function checks the file for for a double
{
double test = inFile.get();
if(inFile.good())
{
inFile.unget();
return true;
}
else
return false;
}
I've heard that using ifstream.good() is a no no for reading the end of a file, but in this simple example, it was the quickest solution.