Visual Studio 2008中if…

1. Behaviors

The same code by a student has two different behavior in Visual Studio 2008 and g++ in codepad.org:
(1) in VC++, if a read operation finished and the file pointer is now in file end, eof() still tells false, only after you call read operation again, eof() bit then will be set.
(2) in g++, if a a read operation finished and the file pointer is reach file end, eof() will return true.

2. Root cause
  (1) When eofbit will be set in istream?
      In VC ++ istream::read() calls _Read_s(), and _Read_s() sets eofbit only when read bytes is less than expected bytes.
  (1) How eof() works in C++ iostream in Visual Studio?
      In VC++ istream::eof() check and only check member _State, so it won't directly check istream actual status, so it just depend on the last read() operation.


3. Source code of istream::read() and istream::_Read_s(...):


=======================================================================================
Appendix A: Source code of VC ++, related to istream::eof()
=======================================================================================

_Myt& __CLR_OR_THIS_CALL _Read_s(_Elem *_Str, size_t _Str_size, streamsize _Count)
{ // read up to _Count characters into buffer
_DEBUG_POINTER(_Str);
ios_base::iostate _State = ios_base::goodbit;
_Chcount = 0;
const sentry _Ok(*this, true);

if (_Ok)
{ // state okay, use facet to extract
_TRY_IO_BEGIN
const streamsize _Num = _Myios::rdbuf()->_Sgetn_s(_Str, _Str_size, _Count);
_Chcount += _Num;
if (_Num != _Count)
_State |= ios_base::eofbit | ios_base::failbit; // short read
_CATCH_IO_END
}

_Myios::setstate(_State);
return (*this);
}

_Myt& __CLR_OR_THIS_CALL read(_Elem *_Str, streamsize _Count)
{
return _Read_s(_Str, (size_t)-1, _Count);
}
=======================================================================================
Appendix B: Key test code
=======================================================================================
while(!ifile.eof())
{
ifile.read((char*)&Y,sizeof(T));
if(ifile.fail())
{
    ifile.clear();  // 清楚错误标志;
    ifile.ignore(); // NND, 把无效字符干掉!
            cout<<"----- ONLY Printed by VC++!!!!!!!!! -----"<<endl;

}
else
{
this->EnQueue(Y);       //将数压入队列中
cout<<"   "<<Y;           //测试是否能将对象的数据保留下来
}
}
}

=======================================================================================
Appendix C: full source code
=======================================================================================
// Stupid sina blog always remove something in source code, for example "<>"
// so the following code could not pass building.


#include
#include
#include
#include
#include
using namespace std;

template
class CIntQueue;


template
class Node
{
public:
Node(T data=0,Node* next=NULL)
{
info=data;
link=next;
}

public:
friend class CIntQueue;
private:
T info;
Node * link;

};

template
class CIntQueue
{
public:

    CIntQueue();
    ~CIntQueue()
{
MakeEmpty();
}

bool IsEmpty()               //判断队空
{
return head==NULL;
}


bool EnQueue(const T data); // 将数据压入队列,成功TRUE,失败FALSE
    bool DeQueue(T& data);   // 出对列,得到该元素,成功true,else false

void MakeEmpty();       //置空队列



private:

Node *head,*tail;

};

template
CIntQueue::CIntQueue()
{
head=tail=NULL;
ifstream ifile("queue.ini",ios::binary);
T X,Y;
if(!ifile)
{
ofstream ofile("queue.ini",ios::binary);

srand(time(0));
for(int i=0;i<6;i++)
{
X=rand() % 1000;
cout<<"   "<<X;                   //将对象的数据输出
this->EnQueue(X);
ofile.write((char*)&X,sizeof(T));
}
ofile.close();
ofile.clear();
}

else
{
while(!ifile.eof())
{
ifile.read((char*)&Y,sizeof(T));
if(ifile.fail())
{
ifile.clear();   // 清楚错误标志;
ifile.ignore(); // NND, 把无效字符干掉!
cout<<"-------------- sss ---------------"<<endl;

}
else
{
this->EnQueue(Y);       //将数压入队列中
cout<<"   "<<Y;           //测试是否能将对象的数据保留下来
}
}
}
ifile.close();
ifile.clear();
}
   

template
bool CIntQueue::EnQueue(const T data)
{
Node *tempP=new Node();

if(!tempP)
{
return false;
}

else
{
tempP->info=data;
if(tail==NULL)
    {
head=tail=tempP;
    tempP->link=NULL;
    }
else
    {
tail->link=tempP;
    tempP->link=NULL;
    tail=tempP;
    }

return true;
}
}


template
bool CIntQueue::DeQueue(T& data)
{
if(!IsEmpty())
{
return false;
}
else
{
Node *tempP=head;
if(tempP->info!=data)
{
return false;
}

else
{
head=head->link;
delete tempP;
return true;
}
}
}

template
void CIntQueue::MakeEmpty()
{
Node * tempP;
while(head!=NULL)
{
tempP=head;
head=head->link;
delete tempP;
}
}




int main()
{
CIntQueue Queue;
cout<<endl;
CIntQueue Queue1;
cout<<endl;
CIntQueue Queue2;

return 0;

}
=======================================================================================
Appendix D: "web C++": codepad
=======================================================================================
URL:   http://codepad.org

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值