首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

fstream 的文件指针有关问题

2012-11-09 
fstream 的文件指针问题文件以追加方式打开时,若文件已经存在,为什么tellp返回的仍然是0?eg.C/C++ codestd

fstream 的文件指针问题
文件以追加方式打开时,若文件已经存在,为什么tellp返回的仍然是0?
eg.

C/C++ code
std::ofstream fs;fs.open("out.txt", std::ios::out|std::ios::app);fs << "hello world.";fs.close();fs.open("out.txt", std::ios::out|std::ios::app);// fs << "glad to see you."; // 毫无疑问这个写操作会写到hello world之后if( static_cast<size_t>(fs.tellp()) ){    cout << "out.txt already exists.\n";}fs.close();


HP-UX 或 Win32+VS2008 环境下,上面的代码对文件写指针的测试都是失败的。
又测试了一下Win32 的 CreateFile 函数,用OPEN_ALWAYS打开文件,然后SetFilePointer获取文件指针,得到的文件指针位置也是0,这个倒可以理解,CreateFile不区分读写指针。

难道“tellp指向哪里下一次的写操作就写到哪里”这个规则不成立??那么tellp有什么意义呢?
求解.

[解决办法]
C/C++ code
template<class _E, class _Tr> inline    basic_ostream<_E, _Tr>& __cdecl operator<<(        basic_ostream<_E, _Tr>& _O, const _E *_X)    {typedef basic_ostream<_E, _Tr> _Myos;    ios_base::iostate _St = ios_base::goodbit;    size_t _N = _Tr::length(_X);    size_t _M = _O.width() <= 0 || _O.width() <= _N        ? 0 : _O.width() - _N;    const _Myos::sentry _Ok(_O);    if (!_Ok)        _St |= ios_base::badbit;    else        {_TRY_IO_BEGIN        if ((_O.flags() & ios_base::adjustfield)            != ios_base::left)            for (; 0 < _M; --_M)                if (_Tr::eq_int_type(_Tr::eof(),                    _O.rdbuf()->sputc(_O.fill())))                    {_St |= ios_base::badbit;                    break; }        if (_St == ios_base::goodbit            && _O.rdbuf()->sputn(_X, _N) != _N)            _St |= ios_base::badbit;        if (_St == ios_base::goodbit)            for (; 0 < _M; --_M)                if (_Tr::eq_int_type(_Tr::eof(),                    _O.rdbuf()->sputc(_O.fill())))                    {_St |= ios_base::badbit;                    break; }        _O.width(0);        _CATCH_IO_(_O) }    _O.setstate(_St);    return (_O); }
[解决办法]
使用ios::app模式,新内容只会写到文件的后面,所以seekp、tellp没有起作用,但使用seekp后用tellp返回的位置是正确的。
在if( static_cast<size_t>(fs.tellp()) )前加上fs.seekp(0,ios::end);即可
要用tellp就别用app模式

热点排行