Chinaunix首页 | 论坛 | 博客
  • 博客访问: 987897
  • 博文数量: 158
  • 博客积分: 4380
  • 博客等级: 上校
  • 技术积分: 2367
  • 用 户 组: 普通用户
  • 注册时间: 2006-09-21 10:45
文章分类

全部博文(158)

文章存档

2012年(158)

我的朋友

分类: C/C++

2012-11-26 15:54:57

fstream的读写测试

这是一个简单的程序,将文件中的'i'转化为'I',其中最关键的一步是 seekp( 0, cur ),其目的是使得读和写重新协调起来。
test.txt中的内容是“1i2i3i4i5”
#include
#include
using namespace std;

int main( void )
{
    fstream f( "C:\\test.txt", ios_base::in|ios_base::out|ios_base::binary );
    if( f )
    {
        for( char c; f.read(&c,1); )
        {
            if( c == 'i' )
            {
                f.seekp( -1, ios_base::cur );
                f.write( "I", 1 );
                f.seekp( 0, ios_base::cur );
            }
        }

        f.close();
    }

    return 0;
}
使用 MinGW(gcc3.5.0) 测试,结果正确
使用 VC2008 测试,死循环

于是将 f.seekp( 0, ios_base::cur ) 改为 f.sync()或f.flush(),即代码变为
int main( void )
{
    fstream f( "C:\\test.txt", ios_base::in|ios_base::out|ios_base::binary );
    if( f )
    {
        for( char c; f.read(&c,1); )
        {
            if( c == 'i' )
            {
                f.seekp( -1, ios_base::cur );
                f.write( "I", 1 );
                f.flush(); // 和使用f.sync()效果一样
                // f.tellp();
            }
        }

        f.close();
    }

    return 0;
}
使用 VC2008 测试,结果正确
使用 MinGW(gcc3.5.0) 测试,只有第一个i被修改成功。但如果再在其后增加一个没用的f.tellp()它却也能成功。

按ISO C99的说法:
When a file is opened with update mode ('+' as the second or third character in the
above list of mode argument values), both input and output may be performed on the
associated stream. However, output shall not be directly followed by input without an
intervening call to the fflush function or to a file positioning function (fseek,
fsetpos, or rewind), and input shall not be directly followed by output without an
intervening call to a file positioning function, unless the input operation encounters end-
of-file.
但测试结果是:VC用flush没问题,mingw用seek没问题,也就是说都有问题

阅读(1411) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~

网友评论2012-11-26 15:55:32

redcoder
// f.seekp(0, ios_base::cur);
f.seekp( -1, ios_base::cur );
f.seekp( 1, ios_base::cur );

vc7里面替换一下,发现又可以了。看来问题出在seekp里面的参数判断。
f.seekp(0, ios_base::cur)直接使其进入一个未知状态。