std::ios::in与std::ios::out为什么in是读取数据而out是向文件写入数据,以及打开文件时用std::ios::binary | std::ios::in中的in是否多余?

文件操作

问题1 std::ios::in为什么是读取文件

在使用C++操作文件时经常遇到需要对文件进行读写操作,但是有个比较有意思的现象就是读取文件内容使用std::ios::in,向文件写入时设置的std::ios::out,再看下注释:

/// Perform input and output in binary mode (as opposed to text mode).
/// This is probably not what you think it is; see
/// https://gcc.gnu.org/onlinedocs/libstdc++/manual/fstreams.html#std.io.filestreams.binary
static const openmode binary =	_S_bin;

/// Open for input.  Default for @c ifstream and fstream.
static const openmode in =		_S_in;

/// Open for output.  Default for @c ofstream and fstream.
static const openmode out =		_S_out;

in注释的事 Open for input,很多同学读到这里就怀疑自己学的英语是不是写错了,这里命名写的是input为啥是读取文件???
如果你也有这个疑惑,那说明你把作用对象搞混了,这里的input相对于ifstream 或者fstream来说的,向ifstream input数据,可不就是从文件中读取数据吗。

问题2 std::ios::in在使用ifstream的时候是否多余

在打开文件时,我们常用这样的方式打开文件std::ifstream file(filename, std::ios::binary | std::ios::in); ,其实这里的std::ios::in写上就是良好的编程习惯,就算你不写ifstream构造函数中也是会默认添加上的。

在这里插入图片描述
图片来源

如果有源码直接查看stl官方源码的注释也能看到这样的注释 Open for input. Default for @c ifstream and fstream. ,说明在ifstream对象或者fstream中,默认就是设置了std::ios::in的

示例代码

#include <iostream>
#include <fstream>
#include <cstdint> // for uint32_t

int main() {
    const char* filename = "example.txt"; // 文件名
    std::ifstream file(filename, std::ios::binary | std::ios::ate); // 打开文件,ate模式将文件指针移动到文件末尾

    if (!file.is_open()) {
        std::cerr << "无法打开文件: " << filename << std::endl;
        return 1; // 返回错误码
    }

    // 获取文件大小
    uint32_t fileSize = static_cast<uint32_t>(file.tellg());
    std::cout << "文件大小为: " << fileSize << " 字节" << std::endl;

    // 假设你想从第100个字节开始读取50个字节的内容
    const uint32_t offset = 100; // 起始偏移量
    const uint32_t length = 50; // 需要读取的长度

    // 将文件指针移动到指定的位置
    file.seekg(offset, std::ios::beg);

    // 检查是否成功移动
    if (file.fail()) {
        std::cerr << "无法将文件指针移动到指定位置." << std::endl;
        file.clear(); // 清除状态标志
        file.seekg(0, std::ios::beg); // 移动回文件开头
        return 1;
    }

    // 准备一个缓冲区用来存储读取的数据
    char buffer[length];
    file.read(buffer, length);

    // 检查是否成功读取数据
    if (file.gcount() != length) { // gcount()返回实际读取的字节数
        std::cerr << "无法读取指定长度的数据." << std::endl;
        file.clear(); // 清除状态标志
        file.seekg(0, std::ios::beg); // 移动回文件开头
        return 1;
    }

    // 输出读取的数据
    std::cout << "读取的数据: ";
    for (uint32_t i = 0; i < length; ++i) {
        std::cout << buffer[i];
    }
    std::cout << std::endl;

    // 关闭文件
    file.close();

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Achilles.Wang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值