eof函数如何在cpp上运行?

时间:2015-02-20 11:35:25

标签: c++ eof

我知道这个功能" eof" (cpp)返回" True"只有在错误地尝试从文件中读取之后(而不是当我到达文件末尾时)

因此,如果我们想将所有文件从1移动到另一个,我们必须

infile.get(c);
while ( !infile.eof() )
{
   outfile << c;
   infile.get(c);
}

而不是

while ( !infile.eof() )
{
   infile.get(c);
   outfile <<c;
}

因为如果我们采用seconde方式,最后一个char将复制2次

但是在另一个程序中它不能像那样工作

我创建文件grades.txt并在其上写下&#34; dani&#34;

这样的代码:

ifstream inGrade("grades.txt");
ofstream outRoster("roster.txt");

int tmpGrade;
inGrade >> tmpGrade;

while (!inGrade.eof() ) 
{

    outRoster << tmpGrade <<endl ;
    inGrade >> tmpGrade;
}

它创建了roster.txt&#34;但没有任何内容。

但是如果我使用这段代码:

ifstream inGrade("grades.txt");
ofstream outRoster("roster.txt");

int tmpGrade;


while (!inGrade.eof() ) 
{
    inGrade >> tmpGrade;
    outRoster << tmpGrade <<endl ;

}

它将创建roster.txt并复制&#34; dani&#34;到那里

为什么???为什么在这个例子中eof在我们到达文件末尾时返回false,而不是在错误地尝试从文件读取之后。

2 个答案:

答案 0 :(得分:1)

  

我创建文件grades.txt并写上这个“dani”

所有读取操作都应该失败,因为“dani”不能作为整数提取。这将设置流的failbit但不消耗任何字符,因此不会设置eofbit。你的程序都应该陷入无限循环。

  

修复我没有把dani放到“100”

好的,那么你就不会得到无限循环:)我写了一个程序来演示这个问题:

istringstream input("100");
int foo;

cout << "Reading int succesfully" << endl;
input >> foo;
cout << "!input:\t" << boolalpha << !input << endl;
cout << "input.eof():\t" << boolalpha << input.eof() << " << pay attention" << endl << endl;
cout << "Attempting to read eof" << endl;
input >> foo;
cout << "!input:\t" << boolalpha << !input << endl;
cout << "input.eof():\t" << boolalpha << input.eof() << endl << endl;

input.clear();
input.str("c");
char c;

cout << "Reading char succesfully" << endl;
input >> c;
cout << "!input:\t" << boolalpha << !input << endl;
cout << "input.eof():\t" << boolalpha << input.eof() << " << pay attention"  << endl << endl;
cout << "Attempting to read eof" << endl;
input >> c;
cout << "!input:\t" << boolalpha << !input << endl;
cout << "input.eof():\t" << boolalpha << input.eof() << endl << endl;

输出:

Reading int succesfully
!input:      false
input.eof(): true << pay attention

Attempting to read eof
!input:      true
input.eof(): true

Reading char succesfully
!input:      false
input.eof(): false << pay attention

Attempting to read eof
!input:      true
input.eof(): true

因此,与阅读格式化输入(例如数字)时相比,阅读单个字符时eofbit的行为会有所不同。

因此,如果您想要修改循环版本,使其对数字和字符的行为方式相同,则需要使用bool转换而不是eof()来检查流状态。此外,这将防止无效输入无限循环。您可以使用fail()代替但不检查badbit,以便在出现i / o错误时不会有所需的行为。

infile.get(c);
while (infile) // or !infile.fail() if you have infallible hardware
{
   // use c
   infile.get(c);
}

应该和

一样好用
int tmpGrade;
inGrade >> tmpGrade;
while (inGrade) 
{
    // use tmpGrade
    inGrade >> tmpGrade;
}

但是,您的方法会重复输入调用。您可以通过在循环条件中获取输入来避免这种情况:

while (inGrade >> tmpGrade)
{
    // use tmpGrade
}

答案 1 :(得分:0)

如果在读取值时到达文件末尾,则格式化输入将触发文件结束条件。这意味着如果输入文件中没有任何内容,那么“已更正”的循环将无法输出最终值。特别是,如果输入文件中只有一个值,则不会有任何输出。

您需要继续尝试读取,直到读取失败,而不是检查文件的结尾。最后一个值不会失败(但可能会设置eof);之后的下一次尝试将失败,表明你应该停止。

作为奖励,执行此操作的代码比从后到前循环更容易混淆:

while (inGrade >> tmpGrade) {
    outRoster << tmpGrade << endl;
}