文件操作

问题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;
}
Logo

GitCode 天启AI是一款由 GitCode 团队打造的智能助手,基于先进的LLM(大语言模型)与多智能体 Agent 技术构建,致力于为用户提供高效、智能、多模态的创作与开发支持。它不仅支持自然语言对话,还具备处理文件、生成 PPT、撰写分析报告、开发 Web 应用等多项能力,真正做到“一句话,让 Al帮你完成复杂任务”。

更多推荐