【问题标题】:Why won't this file read in successfully?为什么这个文件不能成功读入?
【发布时间】:2017-04-29 23:41:10
【问题描述】:

我试图读取如下所示的 .dat 文件:

T001CD1              10000.00             2.5         2
T001CD2              50000.00             3.5         6
H407CD1             20000.00             2.0         1
M555CD1            30000.00             3.5         5
N423CD1             50000.00             3.0         4
N423CD2             60000.00             2.5         2
S602CD1              80000.00             4.0         8
H707CD1             25000.00             2.5         7

使用此代码:

void readCdAccountInfo()
{
ifstream in_stream;


in_stream.open("CdAccounts.dat");

while (!in_stream.eof())
{ 
int i = 0;
string iDTemp;
float ratetemp;
int yeartemp;
double depotemp;
while (in_stream
    >> iDTemp
    >> depotemp
    >> ratetemp
    >> yeartemp
     )

{
    CCdAccount temp(iDTemp, depotemp, ratetemp, yeartemp);
    accounts[i] = temp;
    i++;
}

{
    if (in_stream.fail())
    {
        cout << "Input file opening failed. \n";
        exit(1);
    }

    in_stream.close();
}}
}

ID、存款(私人会员)、利率和年份都是我所拥有的课程的一部分。

当我运行 main 时,唯一弹出的是输入文件失败消息。

【问题讨论】:

  • 你有没有用调试器单步调试代码,看看它在失败之前是否成功地通过了循环?
  • 这是我第一次看到有人在阅读完整个文件后,在关闭文件之前报告“打开失败”。
  • 到达文件末尾会为流设置eofbit。但是,尝试读取某些内容的操作(如operator&gt;&gt;())也会设置failbit,如果到达文件末尾会导致它们失败(即不接收输入)。这将导致in_stream.fail() 在while 语句中的in_stream &gt;&gt; iDTemp &gt;&gt; depotemp &gt;&gt; ratetemp &gt;&gt; yeartemp 到达文件末尾时变为真。
  • 外部while 循环看起来很奇怪,因为你的内部while 已经读取了所有记录。

标签: c++ ifstream


【解决方案1】:

首先,在打开文件后立即检查打开错误。

ifstream in_stream("CdAccounts.dat");
if (in_stream.fail())
{
    cout << "Input file opening failed. \n";
    exit(1);
}

外部循环while (!in_stream.eof()) 已过时,因为您已经正确检查了内部循环中的流错误。

在下面的代码中,我不知道变量accounts的类型,但它似乎是一个数组。它与您遇到的问题没有直接关系,但如果文件包含的记录多于您为数组保留的记录,则该数组可能会溢出。我建议改用std::vector,它会自动调整大小。

int i = 0;
string iDTemp;
float ratetemp;
int yeartemp;
double depotemp;

while (in_stream
    >> iDTemp
    >> depotemp
    >> ratetemp
    >> yeartemp
     )
{
    CCdAccount temp(iDTemp, depotemp, ratetemp, yeartemp);

    // Instead of this...
    accounts[i] = temp;
    i++;

    // ... I suggest declaring accounts as std::vector<CCdAccount>
    //     so you could add elements like this:
    // accounts.push_back( temp );
}

下一个问题是在此代码之后的错误检查。正如评论者彼得指出的那样:

到达文件末尾设置流的 eofbit。然而,运营 尝试读取某些内容(例如 operator>>())也设置了 如果到达文件末尾导致它们失败(即不 接收输入)。

因此,要仅检查 意外 读取错误,我们必须从错误条件中排除 eof 位:

if (in_stream.fail() && ! in_stream.eof())
{
    cout << "Input file reading failed.\n";
    exit(1);
}

在函数结束时不需要显式地close() 流,因为流的析构函数会在作用域结束时自动关闭文件。调用close() 不是错误,只是已经过时了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多