首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

C++ Practical-2 day12 读写文件综合题

  • 25-02-19 07:41
  • 2497
  • 13838
blog.csdn.net

系列文章目录

点击直达——文章总目录


文章目录

  • 系列文章目录
  • C++ Practical-2 day12 读写文件综合题
    • Overview
    • 1.读写文件综合题
      • 1.1.写入文件
      • 1.2.读取文件
      • 1.3.主函数
      • 1.4.完整代码
    • 2.如何使用 C++ 进行更复杂的文件读写,比如追加内容或者以二进制模式读写?
      • 2.1.追加模式
      • 2.2.二进制读写模式
      • 2.3.主函数
      • 2.4.注意事项
    • 3.在C++中,除了使用文件流,还有哪些方法可以进行文件操作?
    • 4.在C++中,如何检查文件读写操作是否成功,以及在失败时如何处理错误?
      • 4.1.检查文件操作是否成功
      • 4.2.错误处理
    • 5.如果文件读写操作失败,我应该如何优雅地处理异常,而不是直接崩溃程序?
      • 5.1. 检查流状态
      • 5.2. 使用异常处理
      • 5.3. 提供错误反馈
      • 5.4. 资源清理
      • 5.5. 记录日志
      • 5.6.示例代码
      • 5.7.注意事项
    • 关于作者


C++ Practical-2 day12 读写文件综合题

Overview

  • C++不练习coding,就相当于空中楼阁,基础不扎实
  • 光吃不干,等于没吃

1.读写文件综合题

在 C++ 中,读写文件是一个常见的任务。我们可以使用标准的文件流(std::ifstream 用于读取,std::ofstream 用于写入)来处理文件操作。以下是一个综合示例,展示了如何在 C++ 中创建一个文件,写入一些内容,然后读取并显示这些内容。

1.1.写入文件

首先,我们将创建一个函数来写入文件:

#include 
#include 

void writeToFile(const std::string& filename, const std::string& content) {
    std::ofstream outFile(filename); // 创建一个 ofstream 对象并打开文件
    if (!outFile) {
        std::cerr << "Unable to create file " << filename << std::endl;
        return;
    }

    outFile << content; // 写入内容到文件
    outFile.close(); // 关闭文件
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

1.2.读取文件

接下来,我们将创建一个函数来读取文件:

void readFromFile(const std::string& filename) {
    std::ifstream inFile(filename); // 创建一个 ifstream 对象并打开文件
    if (!inFile) {
        std::cerr << "Unable to open file " << filename << std::endl;
        return;
    }

    std::string line;
    while (std::getline(inFile, line)) { // 逐行读取文件内容
        std::cout << line << std::endl;
    }

    inFile.close(); // 关闭文件
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

1.3.主函数

最后,我们在 main 函数中使用这些函数:

int main() {
    std::string filename = "example.txt";
    std::string content = "Hello, World!\nThis is a test file.\n";

    // 写入文件
    writeToFile(filename, content);

    // 读取文件
    readFromFile(filename);

    return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

1.4.完整代码

将以上代码片段组合在一起,我们得到一个完整的程序:

#include 
#include 
#include 

void writeToFile(const std::string& filename, const std::string& content) {
    std::ofstream outFile(filename);
    if (!outFile) {
        std::cerr << "Unable to create file " << filename << std::endl;
        return;
    }

    outFile << content;
    outFile.close();
}

void readFromFile(const std::string& filename) {
    std::ifstream inFile(filename);
    if (!inFile) {
        std::cerr << "Unable to open file " << filename << std::endl;
        return;
    }

    std::string line;
    while (std::getline(inFile, line)) {
        std::cout << line << std::endl;
    }

    inFile.close();
}

int main() {
    std::string filename = "example.txt";
    std::string content = "Hello, World!\nThis is a test file.\n";

    writeToFile(filename, content);
    readFromFile(filename);

    return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39

这个程序首先创建一个名为 example.txt 的文件,并向其中写入一些文本内容。然后,程序读取该文件的内容,并将其输出到控制台。这是一个简单的文件读写示例,展示了 C++ 中基本的文件操作。

2.如何使用 C++ 进行更复杂的文件读写,比如追加内容或者以二进制模式读写?

在 C++ 中,进行更复杂的文件读写操作可以通过指定文件打开模式来实现。以下是一些常见的文件操作模式:

2.1.追加模式

在追加模式下打开文件,所有写入操作都会从文件末尾开始追加内容。在 std::ofstream 中,可以使用 std::ios::app 模式来追加内容。

#include 
#include 
#include 

void appendToFile(const std::string &filename, const std::string &content) {
    std::ofstream outFile(filename, std::ios::app); // 以追加模式打开文件
    if (!outFile) {
        std::cerr << "Unable to open file " << filename << std::endl;
        return;
    }

    outFile << content; // 追加内容到文件
    outFile.close();    // 关闭文件
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

2.2.二进制读写模式

在二进制模式下读写文件,可以使用 std::ios::binary 模式。这在处理非文本文件(如图片、音频、视频等)时非常有用。

#include 
#include 

void writeBinaryFile(const std::string& filename, const std::vector<char>& data) {
    std::ofstream outFile(filename, std::ios::binary); // 以二进制模式打开文件
    if (!outFile) {
        std::cerr << "Unable to create binary file " << filename << std::endl;
        return;
    }

    outFile.write(data.data(), data.size()); // 写入二进制数据
    outFile.close(); // 关闭文件
}

void readBinaryFile(const std::string& filename, std::vector<char>& buffer) {
    std::ifstream inFile(filename, std::ios::binary); // 以二进制模式打开文件
    if (!inFile) {
        std::cerr << "Unable to open binary file " << filename << std::endl;
        return;
    }

    inFile.seekg(0, std::ios::end); // 移动到文件末尾
    size_t fileSize = inFile.tellg(); // 获取文件大小
    inFile.seekg(0, std::ios::beg); // 回到文件开头

    buffer.resize(fileSize); // 调整缓冲区大小
    inFile.read(buffer.data(), fileSize); // 读取文件内容到缓冲区
    inFile.close(); // 关闭文件
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

2.3.主函数

在 main 函数中,我们可以调用这些函数来执行追加和二进制读写操作。

int main() {
    std::string filename = "example.txt";
    std::string textContent = "This is additional text.\n";

    // 追加文本内容
    appendToFile(filename, textContent);

    // 二进制写入
    std::vector<char> binaryData = { 0x00, 0x01, 0x02, 0x03, 0x04 };
    writeBinaryFile("binaryData.bin", binaryData);

    // 二进制读取
    std::vector<char> readData;
    readBinaryFile("binaryData.bin", readData);

    // 显示读取的二进制数据
    for (char c : readData) {
        std::cout << std::hex << (int)c << " ";
    }
    std::cout << std::endl;

    return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

2.4.注意事项

  • 在写入二进制文件时,确保数据是正确的二进制格式。
  • 在读取二进制文件时,确保缓冲区足够大,以存储整个文件的内容。
  • 使用二进制模式时,文件的读写不会受到换行符的影响,这与文本模式不同。

这些示例展示了如何在 C++ 中执行更复杂的文件操作,包括追加内容和以二进制模式读写文件。

3.在C++中,除了使用文件流,还有哪些方法可以进行文件操作?

在 C++ 中,除了使用文件流(如 std::ifstream 和 std::ofstream),还有一些其他方法可以进行文件操作:

  1. C 风格的文件操作:
    使用 C 语言的文件操作函数,如 fopen, fclose, fread, fwrite, fprintf, fscanf 等。

    FILE* file = fopen("example.txt", "w"); // 打开文件用于写操作
    if (file != nullptr) {
        fprintf(file, "Hello, World!\n");
        fclose(file); // 关闭文件
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
  2. C++17 文件系统库 (std::filesystem):
    C++17 引入了 std::filesystem 库,提供了更现代的文件系统操作接口。

    #include 
    namespace fs = std::filesystem;
    
    fs::path filePath = "example.txt";
    fs::create_directory("example_dir"); // 创建目录
    fs::copy("source.txt", "destination.txt"); // 复制文件
    fs::remove("example.txt"); // 删除文件
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
  3. C++标准库中的其他流:
    使用 std::stringstream 或 std::istringstream 和 std::ostringstream 进行字符串和文件内容之间的转换。

    std::stringstream ss;
    ss << "Hello, World!" << std::endl;
    std::string fileContent = ss.str(); // 将流内容转换为字符串
    
    • 1
    • 2
    • 3
  4. 低级文件 I/O 操作:
    使用操作系统提供的系统调用来直接操作文件,如 UNIX/Linux 系统中的 open, read, write, close 等系统调用。

    #include 
    #include 
    
    int fd = open("example.txt", O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
    if (fd != -1) {
        const char* text = "Hello, World!";
        write(fd, text, strlen(text));
        close(fd);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
  5. 内存映射文件:
    使用操作系统提供的内存映射文件功能,如 Windows 的 CreateFileMapping 和 MapViewOfFile,或 UNIX/Linux 的 mmap 系统调用。

    #include 
    #include 
    #include 
    
    int fd = open("example.txt", O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
    write(fd, "Hello, World!", 13);
    ftruncate(fd, 13); // 调整文件大小
    
    // 映射文件到内存
    void* addr = mmap(nullptr, 13, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    if (addr != MAP_FAILED) {
        // 使用映射的内存
        munmap(addr, 13); // 解除映射
    }
    close(fd);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
  6. 第三方库:
    使用第三方库,如 Boost.Filesystem,提供了跨平台的文件系统操作功能。

    #include 
    boost::filesystem::path filePath = "example.txt";
    boost::filesystem::create_directory("example_dir");
    boost::filesystem::copy_file("source.txt", "destination.txt");
    boost::filesystem::remove("example.txt");
    
    • 1
    • 2
    • 3
    • 4
    • 5
  7. 标准库中的其他工具:
    使用 std::tmpfile 创建临时文件,这些文件在程序结束时自动删除。

    FILE* tempFile = std::tmpfile();
    if (tempFile != nullptr) {
        fprintf(tempFile, "Temporary data");
        rewind(tempFile); // 回到文件开头
        // 读取或处理文件...
        fclose(tempFile); // 关闭文件,文件内容会被删除
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

这些方法提供了不同级别的文件操作控制,从底层系统调用到高级抽象,可以根据具体需求和平台特性选择合适的方法。

4.在C++中,如何检查文件读写操作是否成功,以及在失败时如何处理错误?

在 C++ 中,检查文件读写操作是否成功通常涉及到检查文件流的状态。std::fstream、std::ifstream 和 std::ofstream 都提供了成员函数 fail() 和 bad() 来检查流的状态。

4.1.检查文件操作是否成功

  1. 使用 fail() 函数:
    fail() 函数在流遇到任何形式的输入/输出失败时返回 true。

    std::ofstream outFile("example.txt");
    if (outFile.fail()) {
        std::cerr << "Failed to open file for writing." << std::endl;
    } else {
        outFile << "Hello, World!" << std::endl;
        if (outFile.fail()) {
            std::cerr << "Failed to write to file." << std::endl;
        }
    }
    outFile.close();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
  2. 使用 bad() 函数:
    bad() 函数在流遇到不可恢复的错误时返回 true,如读写错误。

    std::ifstream inFile("example.txt");
    if (inFile.bad()) {
        std::cerr << "Failed to open file for reading." << std::endl;
    } else {
        std::string line;
        while (std::getline(inFile, line)) {
            if (inFile.bad()) {
                std::cerr << "Failed to read from file." << std::endl;
                break;
            }
            std::cout << line << std::endl;
        }
    }
    inFile.close();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
  3. 检查特定操作的状态:
    每次读写操作后,可以立即检查操作是否成功。

    std::ofstream outFile("example.txt", std::ios::app);
    outFile << "Appending text." << std::endl;
    if (!outFile) { // 等同于检查 fail() 或 bad()
        std::cerr << "Write operation failed." << std::endl;
    }
    outFile.close();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

4.2.错误处理

  1. 关闭文件:
    如果检测到错误,应该关闭文件以释放资源。

    if (outFile.fail()) {
        outFile.close();
        // 进一步的错误处理...
    }
    
    • 1
    • 2
    • 3
    • 4
  2. 抛出异常:
    可以在检测到错误时抛出异常,让上层代码处理。

    if (outFile.fail()) {
        throw std::runtime_error("Failed to write to file.");
    }
    
    • 1
    • 2
    • 3
  3. 返回错误代码:
    在函数中返回错误代码,让调用者根据错误代码进行处理。

    bool writeFile(const std::string& filename, const std::string& content) {
        std::ofstream outFile(filename);
        if (outFile.fail()) {
            return false;
        }
        outFile << content;
        if (outFile.fail()) {
            outFile.close();
            return false;
        }
        outFile.close();
        return true;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
  4. 使用错误码:
    定义错误码枚举或类,用于表示不同的错误情况。

    enum class FileError {
        None,
        OpenFailed,
        WriteFailed,
        CloseFailed
    };
    
    FileError writeFile(const std::string& filename, const std::string& content) {
        std::ofstream outFile(filename);
        if (outFile.fail()) {
            return FileError::OpenFailed;
        }
        outFile << content;
        if (outFile.fail()) {
            outFile.close();
            return FileError::WriteFailed;
        }
        if (!outFile.close()) {
            return FileError::CloseFailed;
        }
        return FileError::None;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
  5. 记录错误信息:
    使用日志记录错误信息,便于调试和跟踪问题。

    if (outFile.fail()) {
        logError("File writing failed.");
        // 进一步的错误处理...
    }
    
    • 1
    • 2
    • 3
    • 4
  6. 资源泄漏处理:
    确保在发生错误时释放已分配的资源,避免资源泄漏。

  7. 用户提示:
    在 GUI 应用程序或需要用户交互的场景中,向用户显示错误信息。

  8. 重试机制:
    在某些情况下,如果操作失败,可以实施重试机制。

通过这些方法,你可以在 C++ 中有效地检查文件操作是否成功,并在失败时进行适当的错误处理。

5.如果文件读写操作失败,我应该如何优雅地处理异常,而不是直接崩溃程序?

在 C++ 中,优雅地处理文件读写操作失败的异常,而不是让程序直接崩溃,通常涉及到以下几个步骤:

5.1. 检查流状态

在进行文件操作之前和之后,检查文件流的状态。这可以通过检查流对象的 fail()、bad() 或 eof() 成员函数来实现。

5.2. 使用异常处理

使用 try 和 catch 块来捕获和处理可能抛出的异常。

5.3. 提供错误反馈

向用户提供清晰的错误信息,而不是让程序默默失败。

5.4. 资源清理

确保在发生异常时释放所有已分配的资源。

5.5. 记录日志

记录错误日志,以便于后续分析和调试。

5.6.示例代码

以下是一个示例,展示了如何在文件操作中使用异常处理:

#include 
#include 
#include 

void writeToFile(const std::string& filename, const std::string& content) {
    std::ofstream outFile(filename);
    if (!outFile) {
        throw std::runtime_error("Unable to open file for writing: " + filename);
    }

    outFile << content;
    if (outFile.fail()) {
        outFile.close();
        throw std::runtime_error("Failed to write to file: " + filename);
    }

    outFile.close();
}

void readFromFile(const std::string& filename) {
    std::ifstream inFile(filename);
    if (!inFile) {
        throw std::runtime_error("Unable to open file for reading: " + filename);
    }

    std::string line;
    while (std::getline(inFile, line)) {
        if (inFile.fail()) {
            inFile.close();
            throw std::runtime_error("Failed to read from file: " + filename);
        }
        std::cout << line << std::endl;
    }

    inFile.close();
}

int main() {
    std::string filename = "example.txt";
    std::string content = "Hello, World!\n";

    try {
        writeToFile(filename, content);
        readFromFile(filename);
    } catch (const std::exception& e) {
        std::cerr << "Error: " << e.what() << std::endl;
        // 这里可以进行额外的错误处理,如用户提示、日志记录等
    }

    return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51

5.7.注意事项

  1. 不要吞没异常:不要捕获异常而不处理,至少提供错误反馈或记录日志。
  2. 资源管理:使用 RAII(资源获取即初始化)原则管理资源,确保资源在异常发生时也能被正确释放。
  3. 用户友好:提供用户友好的错误信息,避免显示复杂的技术细节。
  4. 日志记录:记录详细的错误日志,以便于问题追踪和调试。
  5. 异常安全:确保程序在抛出和捕获异常时不会泄露资源或留下不可用的状态。

通过这些方法,你可以确保文件读写操作失败时,程序能够优雅地处理异常,而不是直接崩溃。


关于作者

  • 微信公众号:WeSiGJ
  • GitHub:https://github.com/wesigj/cplusplusboys
  • CSDN:https://blog.csdn.net/wesigj
  • 微博:
  • -版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
WeSiGJ
微信公众号
共同分享,共同交流, 共同学习!
注:本文转载自blog.csdn.net的WeSiGJ的文章"https://wesigj.blog.csdn.net/article/details/142603635"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2491) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

101
推荐
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2025 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top