РЕДАКТИРОВАТЬ: первоначально я думал, что это из-за различных IDE, на которых я тестировал программу. Проблема, похоже, сужена до отдельных компиляторов, которые использует каждая IDE.
Для выполнения задания в моем введении в класс C ++ мне нужно было написать программу, которая считывает дубликаты из файла и оценивает их, выводит содержимое в другой файл .txt.
Я написал программу с использованием Visual Studio 2012, и она читает файл, как я ожидал, и исполняется, как и ожидалось
Я считаю, что мой учитель использует Dev C ++, поэтому я скомпилировал тот же код в этой IDE, а также в Code :: Blocks.
Что я заметил, так это то, что указатель get ведет себя по-другому, и я считаю, что это связано с компилятором. В Code :: Blocks и Dev C ++ после чтения первого double (6.0) inFile.tellg () возвращает 15. В VS2012 возвращает 3.
Что я могу сделать с этой программой, чтобы она работала во всех IDE?
Файл для чтения:
Первые 3 числа каждой строки — это размеры коробки, следующие 2 — диаметр и высота банки, чтобы поместиться в коробку.
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
Ожидаемый результат (Выполнено в 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
===========================================================
Выход из Code :: Blocks и 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
===========================================================
И наконец программа:
#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;
}
Я извиняюсь за дамп кода, но я искал и не могу найти надежного объяснения этому или как это исправить.
Я не вижу ничего плохого в коде как таковом.
Глядя на входные данные и сравнивая их с полученными числами, становится ясно, что после прочтения набора из пяти чисел чтение пропускается на девять символов. Это очевидно из-за вызова hasDouble () в конце цикла while — вы уже показали, что на Tellg нельзя положиться, и hasDouble нуждается в его работе.
Итак, чтобы заставить код работать на всех IDE, вам нужно заменить использование hasDouble в цикле каким-то другим способом определения того, что вы достигли конца файла.
Я действительно не могу сказать, почему TellG ведет себя по-другому, но мне кажется, что он сломан в Code :: Blocks и Dev C ++. Возможно, мы ожидаем, что он будет вести себя лучше, чем он есть.
Может быть входной файл P4Boxes.txt отличается?
Действительно неясно, какой каталог будет текущим рабочим каталогом со всеми этими IDE и что там за файл P4Boxes.txt …
Иначе это ошибка …
В то время как я ценю помощь каждого в выяснении источника проблемы, мой учитель смог найти решение проблемы.
Оригинальный код:
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;
}
Код замены:
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;
}
Я слышал, что использование ifstream.good () — нет, нет, для чтения конца файла, но в этом простом примере это было самое быстрое решение.