前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >用fstream读写文件容易犯的错

用fstream读写文件容易犯的错

作者头像
gaigai
发布2019-11-15 10:37:21
4.7K0
发布2019-11-15 10:37:21
举报
文章被收录于专栏:Windows开发Windows开发

系统学习Windows客户端开发

fstream属于C++标准,使用fstream进行文件读写,具有跨平台性。使用过程中要注意几点:

第一,构造函数中指定文件路径时内部会调用open(),如果再次调用open(),调用将会返回失败。

第二,判断文件打开是否成功,使用is_open()接口,不能使用bad()接口,bad()接口是用来判断读写是否有错。

第三,如果文件内容有包含\0,open()时指定fstream::binary标志位进行二进制流的读写。如果写文件希望追加不清除原有内容,open()时指定fstream::app标志位(append的缩写)。

第四,为了计算文件大小,需要先将位置指向结尾,这时要调seekg(0, ios_base::end),而不是seekg(ios_base::end),seekg有两个重载函数,只带一个参数的接口表示相对开始的位置,ios_base::end的值为2,seekg(ios_base::end)表示移到2的位置,而不是文件末尾。

第五,慎用操作符>>和<<读写文件,操作符>>和<<类似于scanf()接口,它是基于字符串格式化输入输出,比如unsigned short x=200, y=300; ofs <<x<<y;文件内容是字符串200300,而不是数值c8002c01,因为操作符<<会先将数值转化为字符串再写入文件。ifs>>x>>y;操作符>>读取x和y时,首先获得字符串200300,再赋值给x,因为x是unsigned short类型最大值为65535,200300超过65535,读取失败。所以某些场景下用操作符<<和>>进行文件读写是不可逆,应该用read(), write()接口读写。

下面代码详细演示fstream的使用及要注意的地方。

代码语言:javascript
复制
#include <string>
#include <fstream>

using namespace std;

#pragma pack(1)
struct CPoint
{
public:
    char m_cType = 0;  // 0 down, 1 up, 2 move
    unsigned short m_nX = 0;
    unsigned short m_nY = 0;
};
#pragma pack()

int main()
{
    const std::wstring strFilePath = L"C:\\test.dat";
    CPoint pt;
    pt.m_cType = 0;
    pt.m_nX = 200;
    pt.m_nY = 300;

    ofstream ofs(strFilePath.c_str(), fstream::out | fstream::binary);
    if (ofs.is_open())
    {
        // 判断文件打开是否成功,使用is_open()
        // 不能使用bad(),bad()用来判断读写有没错误
        // 操作符<<输出整型时,并不是存储数值,而是将数值格式化成字符串后存储,
        // 此时文件内容第一字节是数值0,然后是字符串200300
        ofs << pt.m_cType << pt.m_nX << pt.m_nY;
        ofs.close();
    }

    ifstream ifs(strFilePath.c_str(), fstream::in | fstream::binary);
    if (ifs.is_open())
    {
        // 操作符>>输入整型时,会扫描数字串直到非数字为止,
        // 此时扫描到字符串是200300,然后转化为unsigned short赋值给m_nX,
        // 因为200300超过unsigned short最大值65535,读取失败
        CPoint pt2;
        ifs >> pt2.m_cType >> pt2.m_nX >> pt2.m_nY;
        printf("x= %d, y = %d\n", pt2.m_nX, pt2.m_nY);  // 输出的值是 0, 0
        ifs.close();
    }

    // 下面是正确代码,使用read(),write()来实现
    ofstream ofs2(strFilePath.c_str(), fstream::out | fstream::binary);
    if (ofs2.is_open())
    {    
        ofs2.write((const char*)&pt, sizeof(pt));
        ofs2.close();
    }

    ifstream ifs2(strFilePath.c_str(), fstream::in | fstream::binary);
    if (ifs2.is_open())
    {
        CPoint pt2;
        ifs2.read((char*)&pt2, sizeof(pt2));
        printf("x= %d, y = %d\n", pt2.m_nX, pt2.m_nY);  // 输出的值是 200, 300
        ifs2.close();
    }

    return 0;
}
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-11-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Windows开发 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 系统学习Windows客户端开发
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档