墨香流转:C++文件流的魔法之旅

[前置知识:C文件流](https://blog.csdn.net/qq_56146092/article/details/137136951?spm=1001.2014.3001.5501)

C++ 文件流是C++编程语言中处理文件输入输出(I/O)的一个重要部分,它是基于面向对象的I/O系统设计的,通过将文件看作是一个连续的数据流来进行读取和写入操作。C++ 标准库中的 头文件提供了处理文件流所需的类

std::ifstream 是 C++ 中用于从文件中读取数据的类,它是基于 std::basic_ifstream<char> 的特化版本,适用于处理字符流。以下是一些基本的 std::ifstream 用法示例:

  1. 声明和初始化
  #include <fstream>
  #include <iostream>

  int main() {
      std::ifstream inputFile("example.txt"); // 声明并打开一个名为 "example.txt" 的文件
  }
  1. 检查文件是否成功打开

    if (inputFile.is_open()) {
        std::cout << "File opened successfully.\n";
    } else {
        std::cerr << "Unable to open file.\n";
        return 1; // 或者执行其他错误处理
    }
    
  2. 读取整行

    std::string line;
    while (std::getline(inputFile, line)) { // 逐行读取文件
        std::cout << line << '\n';
    }
    
  3. 读取特定类型的数据

    int number;
    inputFile >> number; // 读取一个整数
    
    double floatingPoint;
    inputFile >> floatingPoint; // 读取一个浮点数
    
    std::string word;
    inputFile >> word; // 读取一个单词(空格分隔)
    
  4. 关闭文件

    inputFile.close();
    
  5. 异常处理

    try {
        inputFile.exceptions(std::ifstream::failbit | std::ifstream::badbit); // 设置抛出异常的标志位
        // 进行读取操作...
    } catch (const std::ios_base::failure& e) {
        std::cerr << "An I/O error occurred: " << e.what() << '\n';
    }
    

注意:在C++11及以后的标准中,由于采用了RAII(Resource Acquisition Is Initialization)原则,当ifstream对象离开其作用域时,会自动调用析构函数关闭文件,因此在大多数情况下无需手动调用 close() 函数。但在某些场景下,比如你需要提前关闭文件或者检测读取是否成功,仍然可以选择显式调用 close()

**

ofstream:

**

代表输出文件流,用于向文件中写入数据。创建一个 ofstream 对象并关联到一个文件后,你就可以通过这个对象将数据写入文件。
  1. 声明和初始化

    #include <fstream>
    #include <iostream>
    
    int main() {
        std::ofstream outputFile("output.txt"); // 声明并创建/打开一个名为 "output.txt" 的文件
    }
    
  2. 检查文件是否成功打开

    if (outputFile.is_open()) {
        std::cout << "File opened successfully for writing.\n";
    } else {
        std::cerr << "Unable to open file for writing.\n";
        return 1; // 或者执行其他错误处理
    }
    
  3. 写入文本或数据

    std::string message = "Hello, World!";
    outputFile << message << '\n'; // 写入字符串
    
    int number = 42;
    outputFile << number << '\n'; // 写入整数
    
    double floatingPoint = 3.14;
    outputFile << floatingPoint << '\n'; // 写入浮点数
    
  4. 追加模式打开文件

    std::ofstream appendFile("output.txt", std::ios_base::app); // 在文件末尾追加内容
    
  5. 写入换行

    outputFile << "\n"; // 写入一个换行符
    
  6. 关闭文件

    outputFile.close();
    

[点击并拖拽以移动]

  1. 异常处理

    try {
        outputFile.exceptions(std::ofstream::failbit | std::ofstream::badbit); // 设置抛出异常的标志位
        // 进行写入操作...
    } catch (const std::ios_base::failure& e) {
        std::cerr << "An I/O error occurred while writing: " << e.what() << '\n';
    }
    

此外,需要注意的是,如果你尝试在没有权限或者磁盘空间不足的情况下打开文件进行写入,可能会导致操作失败。此时,你应该通过 is_open() 和捕获可能抛出的异常来进行错误处理。

示例:

#include <fstream>
#include <iostream>
#include <string>

int main() {
    // 创建并打开一个用于写入的文件流
    std::ofstream outputFile("output.txt");
    
    if (outputFile.is_open()) {
        std::cout << "成功创建一个新的文件" << std::endl;
        
        // 写入文本
        std::string message = "dhasudashduiahduiha d aushduiashd da";
        outputFile << message << "\n";
        
        // 关闭写入流
        outputFile.close();
        
        // 打开同一文件用于读取
        std::ifstream inputFile("output.txt");

        if (inputFile.is_open()) {
            std::string line;

            // 逐行读取并输出
            while (getline(inputFile, line)) {
                std::cout << line << std::endl;
            }

            // 关闭读取流
            inputFile.close();
        } else {
            std::cerr << "无法打开文件进行读取." << std::endl;
        }
    } else {
        std::cerr << "无法创建或打开文件进行写入." << std::endl;
    }

    return 0;
}

fstream

include <fstream.h>

The fstream class is an iostream derivative specialized for combined disk file input and output. Its constructors automatically create and attach a filebuf buffer object.

//fstream类是iostream的派生类,专门用于合并磁盘文件的输入和输出。它的构造函数自动创建并附加一个filebuf缓冲区对象。

fstream类在C++中的应用非常广泛,不仅限于简单的读写文本或二进制数据,还可用于各种复杂的数据持久化场景。以下是一些更具体的应用示例:

示例1:读写结构化数据

struct Record {
    int id;
    std::string name;
    float score;
};

// 写入记录到文件
std::fstream file("records.bin", std::ios::binary | std::ios::out);
Record r1{1, "Alice", 90.5};
file.write(reinterpret_cast<char*>(&r1), sizeof(r1));
Record r2{2, "Bob", 85.0};
file.write(reinterpret_cast<char*>(&r2), sizeof(r2));
file.close();

// 从文件读取记录
std::fstream readfile("records.bin", std::ios::binary | std::ios::in);
Record retrieved;
while (readfile.read(reinterpret_cast<char*>(&retrieved), sizeof(retrieved))) {
    std::cout << "ID: " << retrieved.id << ", Name: " << retrieved.name << ", Score: " << retrieved.score << std::endl;
}
readfile.close();

示例2:读写文本行并修改部分内容:

`std::fstream file("textfile.txt", std::ios::in | std::ios::out);` 这一行代码创建了一个 `std::fstream` 类型的对象 `file`,并尝试打开名为 `"textfile.txt"` 的文件。这里的参数含义如下:
- `"textfile.txt"`:这是要打开的文件的名称,表明你打算与名为 "textfile.txt" 的文本文件进行交互。
- `std::ios::in`:这是一个打开模式标志,表示文件将被用来进行输入操作,即从文件中读取数据。因此,你可以使用 `file` 对象从 "textfile.txt" 文件中读取内容。
- `std::ios::out`:这也是一个打开模式标志,表示文件将被用来进行输出操作,即向文件中写入数据。这意味着你可以在后续代码中使用 `file` 对象将数据写入到 "textfile.txt" 文件中。
综合起来,这一行代码的意思是:创建一个文件流对象 `file`,并以读写模式打开名为 "textfile.txt" 的文件。这样一来,你既可以从中读取数据,也可以向其中写入数据。如果文件不存在,将会创建新文件;如果文件已存在,原有内容将被保留,新写入的内容将追加到文件末尾。如果你想覆盖文件原有内容,需要在写入前调整文件指针位置。在不设置其他特定标志的情况下,此模式默认按照文本模式打开文件,即考虑操作系统特定的文本格式(例如,Windows、Linux和MacOS对换行符的处理方式不同)。
std::fstream file("textfile.txt", std::ios::in | std::ios::out);

if (file.is_open()) {
    std::string line;
    while (std::getline(file, line)) {
        // 查找特定关键词并替换
        size_t pos = line.find("old_word");
        if (pos != std::string::npos) {
            line.replace(pos, strlen("old_word"), "new_word");
            file.seekp(-line.size(), std::ios::cur); // 回到当前行开头
            file.write(line.c_str(), line.size()); // 重写行
        }
    }
    file.close();
}

示例3:追加写入日志

std::fstream logFile("log.txt", std::ios::out | std::ios::app);

if (logFile.is_open()) {
    logFile << "Timestamp: " << getCurrentTime() << ", Event: Some important event happened.\n";
    logFile.flush();
}

logFile.close();

示例4:二进制文件的随机访问

std::fstream binaryFile("binary_data.bin", std::ios::binary | std::ios::in | std::ios::out);

if (binaryFile.is_open()) {
    binaryFile.seekp(100); // 移动到文件偏移量为100的位置
    binaryFile.write(reinterpret_cast<const char*>(&someData), sizeof(someData)); // 在指定位置写入数据

    binaryFile.seekg(100); // 移动到相同位置进行读取
    binaryFile.read(reinterpret_cast<char*>(&retrievedData), sizeof(retrievedData));
}

binaryFile.close();

补充:

在这里插入图片描述
在C++中,文件读写模式通常由一组模式标志组成,这些标志可以组合使用,以控制文件的打开方式。以下是一些常用的文件模式标志:

读取模式

  • std::ios::in: 打开文件用于输入(读取)。

写入模式

  • std::ios::out: 打开文件用于输出(写入)。
  • std::ios::trunc: 如果文件已存在,截断文件,即清空文件内容。

读写模式

  • std::ios::in | std::ios::out: 打开文件用于读写。

追加模式

  • std::ios::app: 打开文件用于追加。如果文件已存在,内容将被追加到文件末尾。

二进制模式

  • std::ios::binary: 以二进制模式打开文件。

文本模式

  • 默认情况下,文件以文本模式打开。

同步模式

  • std::ios::ate: 打开文件时定位到文件末尾。

文件状态

  • std::ios::ate: 打开文件时定位到文件末尾(同上)。
  • std::ios::trunc: 如果文件已存在,截断文件(同上)。

共享模式

  • std::ios::in | std::ios::out: 打开文件用于读写。

示例

以下是一个使用不同模式标志打开文件的示例:

#include <fstream>
#include <iostream>
int main() {
    // 以读取模式打开文件
    std::ifstream file("example.txt", std::ios::in);
    if (!file) {
        std::cerr << "无法打开文件用于读取" << std::endl;
        return 1;
    }
    
    // 以写入模式打开文件
    std::ofstream file("example.txt", std::ios::out);
    if (!file) {
        std::cerr << "无法打开文件用于写入" << std::endl;
        return 1;
    }
    
    // 以读写模式打开文件
    std::fstream file("example.txt", std::ios::in | std::ios::out);
    if (!file) {
        std::cerr << "无法打开文件用于读写" << std::endl;
        return 1;
    }
    
    // 以追加模式打开文件
    std::fstream file("example.txt", std::ios::out | std::ios::app);
    if (!file) {
        std::cerr << "无法打开文件用于追加" << std::endl;
        return 1;
    }
    
    // 以二进制模式打开文件
    std::fstream file("example.bin", std::ios::out | std::ios::binary);
    if (!file) {
        std::cerr << "无法打开文件用于写入" << std::endl;
        return 1;
    }
    
    // 关闭文件
    file.close();
    return 0;
}

请注意,std::ios::instd::ios::out 标志可以组合使用,如 std::ios::in | std::ios::out,以允许同时进行读写操作。此外,如果文件打开模式中包括了 std::ios::trunc,那么如果文件已存在,其内容将被清空。

文件具体使用

下面是一些C++中文件操作的具体运用例子:

1. 读取整个文件内容

#include <fstream>
#include <iostream>
#include <string>
int main() {
    std::ifstream file("example.txt");
    if (!file) {
        std::cerr << "无法打开文件" << std::endl;
        return 1;
    }
    
    std::string line;
    std::string content;
    while (std::getline(file, line)) {
        content += line + "\n";
    }
    
    std::cout << content << std::endl;
    
    file.close();
    return 0;
}

2. 写入文件内容

#include <fstream>
#include <iostream>
int main() {
    std::ofstream file("example.txt");
    if (!file) {
        std::cerr << "无法打开文件" << std::endl;
        return 1;
    }
    
    file << "Hello, world!";
    
    file.close();
    return 0;
}

3. 读取和写入文件

#include <fstream>
#include <iostream>
int main() {
    std::fstream file("example.txt", std::ios::in | std::ios::out);
    if (!file) {
        std::cerr << "无法打开文件" << std::endl;
        return 1;
    }
    
    file << "Hello, world!";
    
    char ch;
    file.get(ch);
    while (file) {
        std::cout << ch;
        file.get(ch);
    }
    
    file.close();
    return 0;
}

4. 追加内容到文件末尾

#include <fstream>
#include <iostream>
int main() {
    std::fstream file("example.txt", std::ios::out | std::ios::app);
    if (!file) {
        std::cerr << "无法打开文件" << std::endl;
        return 1;
    }
    
    file << "Hello, world!";
    
    file.close();
    return 0;
}

5. 文件定位

#include <fstream>
#include <iostream>
int main() {
    std::fstream file("example.txt", std::ios::in | std::ios::out);
    if (!file) {
        std::cerr << "无法打开文件" << std::endl;
        return 1;
    }
    
    file.seekg(0, std::ios::end);  // 定位到文件末尾
    long pos = file.tellg();
    std::cout << "文件大小: " << pos << " 字节" << std::endl;
    
    file.seekg(0, std::ios::beg);  // 定位到文件开头
    char ch;
    file.get(ch);
    while (file) {
        std::cout << ch;
        file.get(ch);
    }
    
    file.close();
    return 0;
}

6. 检查文件是否存在

#include <fstream>
#include <iostream>
int main() {
    std::ifstream file("example.txt");
    if (!file) {
        std::cout << "文件不存在" << std::endl;
    } else {
        std::cout << "文件存在" << std::endl;
    }
    
    return 0;
}

这些例子展示了C++中文件操作的一些基本用法。你可以根据自己的需求进行修改和扩展。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值