1

编辑:最初我认为这是由于我测试程序的不同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;   
}

我为代码转储道歉,但我一直在寻找并且找不到对此或如何修复它的可靠解释。

4

3 回答 3

1

我看不出这样的代码有什么问题。

查看输入数据并将其与您获得的数字进行比较,很明显在读入一组五个数字后,读取会跳过九个字符。这显然是因为在 while 循环结束时调用了 hasDouble() - 您已经表明不能依赖 tellg 并且 hasDouble 需要它才能工作。

因此,要使代码在所有 IDE 上工作,您需要将循环中 hasDouble 的使用替换为其他检测您已到达文件末尾的方法。

我真的不能说为什么 tellg 的行为不同,但在我看来它在 Code::Blocks 和 Dev C++ 中被破坏了。可能是我们期望它表现得比现在更好。

于 2014-02-16T23:54:27.893 回答
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;   
}

替换代码:

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() 不能读取文件末尾,但在这个简单的示例中,它是最快的解决方案。

于 2014-02-17T23:38:49.210 回答
0

可能是输入文件 P4Boxes.txt 不同?目前还不清楚哪个目录将是所有这些 IDE 的当前工作目录以及那里有什么 P4Boxes.txt ......否则这是一个错误......

于 2014-02-17T01:31:02.050 回答