而(f)表现不尽如人意

时间:2017-11-11 11:17:19

标签: c++ file-io while-loop istream

我在codeblocks中面临这个c ++代码的问题...... 这是代码:

#include<iostream>
#include<fstream>
using namespace std;

class test {
   int i;
   float j;
public:
   void getdata() {
       std::cout<<"\nenter i and j:";
       std::cin>>i>>j;
   }
   void putdata() {
       std::cout<<"\ni="<<i<<"\tj="<<j;
   }
};
int main()
{
    test ob,ob1;
    fstream f;
    f.open("dil.txt",ios::out|ios::binary);
    for(int i=0;i<5;i++)
    {
       ob.getdata();
       f.write((char *)& ob,sizeof(ob));
    }
    f.close();
    f.open("dil.txt",ios::in|ios::binary);
    f.seekg(0);
    while(f) {
       f.read((char *)& ob1,sizeof(ob1));
       ob1.putdata();
    }
    f.close();
    return 0;
}

输入详细信息后的输出即将到来:

i=2     j=2.3
i=3     j=3.4
i=4     j=4.5
i=5     j=5.6
i=6     j=6.7
i=6     j=6.7

所以,我的问题是为什么最后的陈述会重演?...请帮助

3 个答案:

答案 0 :(得分:2)

这是因为f仅在read()eof而失败后才会设为假。

尝试这种方式:

while(f.read((char *)& ob1,sizeof(ob1))) {
    ob1.putdata();
}

答案 1 :(得分:1)

代码while(f)通过调用f上的std::basic_ios::operator bool隐式地将bool投射到f

在这种情况下,只要读取该流没有错误,operator bool就会返回true

当您的代码到达文件末尾时,循环测试将调用operator bool并返回true,因为到目前为止,没有错误。然后调用f.read会触发错误,因为它试图读取文件的末尾。

由于流现在处于错误状态,f.read不会更新传递给它的缓冲区,因此缓冲区仍将具有上一次调用中返回的数据。这就是重复最后一个值的原因。

现在,当再次执行循环测试时,operator bool将返回false,因为流处于错误状态,循环将终止。

我在初学者C ++代码中看到了 lot 这个错误。直到我了解了iostream的工作方式,我做了同样的事情。我认为当有人来自一种习惯于在阅读之前测试某种文件末尾功能的语言时,就会发生这种情况。大多数时候,我已经看到iostream的eof函数被用作循环测试。这会导致同样的问题,因为eof没有告诉您已到达流的末尾。它告诉你,你已经试过阅读它了。

C ++ iostream的设计使您可以对读取操作的结果进行循环测试。

答案 2 :(得分:-2)

这是因为如果'f'读取OEF,您必须先控制数据 喜欢这段代码:

#include<iostream>
#include<fstream>
using namespace std;
class test
{int i;float j;
public:
void getdata()
{std::cout<<"\nenter i and j:";
 std::cin>>i>>j;}
void putdata()
{std::cout<<"\ni="<<i<<"\tj="<<j;}
};
int main()
{test ob,ob1;
fstream f;
f.open("dil.txt",ios::out|ios::binary);
for(int i=0;i<5;i++)
{   ob.getdata();
    f.write((char *)& ob,sizeof(ob));
}
f.close();
f.open("dil.txt",ios::in|ios::binary);
f.seekg(0);
while(!f.eof())
{
    f.read((char *)& ob1,sizeof(ob1));
    if(!f.eof())
    {
        ob1.putdata();
    }
}
f.close();
return 0;}