在不同的C ++编译器中读取文件

时间:2014-02-16 23:09:09

标签: c++ file-io compiler-construction g++4.8

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

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

3 个答案:

答案 0 :(得分:1)

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

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

因此,为了使代码适用于所有IDE,您需要在循环中使用hasDouble替换,并使用其他方式检测到您已到达文件的末尾。

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

答案 1 :(得分:0)

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

答案 2 :(得分: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()对于读取文件的末尾是不行的,但在这个简单的例子中,它是最快的解决方案。