35 C++ 文件读取与写入入门

35 C++ 文件读取与写入入门

在 C++ 中,文件的读取与写入是非常重要的操作,可以让程序与外部数据进行交互。下面是关于如何在 C++ 中读取和写入文件的详细教程。

1. 引入头文件

使用文件流之前,我们需要引入头文件 iostreamfstream

1
2
#include <iostream>
#include <fstream>

2. 创建文件输出流 (ofstream)

首先,我们需要创建一个文件输出流来写入文件。可以使用 std::ofstream 类来实现。

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
#include <fstream>

int main() {
std::ofstream outFile("example.txt"); // 创建输出文件流,文件名为 example.txt
if (outFile.is_open()) { // 检查文件是否成功打开
outFile << "Hello, World!" << std::endl; // 写入内容
outFile << "This is a test file." << std::endl; // 写入更多内容
outFile.close(); // 关闭文件
} else {
std::cout << "Unable to open file for writing." << std::endl;
}
return 0;
}

解释:

  • std::ofstream outFile("example.txt"); 创建一个名为 example.txt 的文件,如果文件不存在则会创建它,如果已存在则会覆盖内容。
  • outFile.is_open() 用于检查文件是否被成功打开。
  • 使用 << 操作符可以将内容写入文件。
  • outFile.close(); 用于关闭文件,释放资源。

3. 创建文件输入流 (ifstream)

接下来,我们需要创建一个文件输入流来读取文件。可以使用 std::ifstream 类来实现。

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
#include <fstream>
#include <string>

int main() {
std::ifstream inFile("example.txt"); // 创建输入文件流,文件名为 example.txt
std::string line;
if (inFile.is_open()) { // 检查文件是否成功打开
while (getline(inFile, line)) { // 按行读取文件
std::cout << line << std::endl; // 输出读取的内容
}
inFile.close(); // 关闭文件
} else {
std::cout << "Unable to open file for reading." << std::endl;
}
return 0;
}

解释:

  • std::ifstream inFile("example.txt"); 创建一个文件输入流来读取 example.txt 文件。
  • getline(inFile, line) 用于按行读取文件,直到文件结束。
  • std::cout << line << std::endl; 将读取的每一行输出到控制台。
  • 同样调用 inFile.close(); 来关闭文件。

4. 文件读取与写入注意事项

  • 文件路径:在指定文件名时,可以使用相对路径或绝对路径。例如,"C:/path/to/example.txt"
  • 打开模式:可以在打开文件时指定不同的模式,例如:
    • std::ios::app:以追加模式打开文件。
    • std::ios::in:以只读模式打开文件。
    • std::ios::out:以只写模式打开文件。

例子:以追加模式写入

1
std::ofstream outFile("example.txt", std::ios::app); // 以追加模式打开文件

5. 小结

在本节中,我们学习了如何使用 C++ 中的 ifstreamofstream 类进行文件的读取和写入。掌握这些基本操作后,您就可以在程序中持久化数据,处理配置文件等。

希望这个教程能帮助你从零开始学习 C++ 文件操作的基础概念!如果有任何问题,欢迎随时询问。

36 C++ 进阶到上手实战教程

36 C++ 进阶到上手实战教程

1. 使用构建工具进行持续集成

在现代软件开发中,持续集成(Continuous Integration, CI)是一个重要的实践,它允许开发者频繁地将代码集成到主干上,以便更早地发现问题。在 C++ 开发中,使用合适的构建工具可以显著提高开发效率和代码质量。

1.1 什么是构建工具

构建工具是用来自动化编译、链接和测试代码的程序。它可以管理依赖关系,执行测试并生成发布版本。常见的 C++ 构建工具包括:

  • CMake
  • Makefile
  • Bazel
  • Ninja

在本节中,我们主要讨论如何使用 CMake 来进行持续集成。

1.2 CMake 基础

CMake 是一个跨平台的构建工具,它通过 CMakeLists.txt 文件来配置构建过程。以下是一个简单的 CMakeLists.txt 示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
cmake_minimum_required(VERSION 3.10)
project(MyProject)

# 设置 C++ 标准
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED True)

# 添加可执行文件
add_executable(my_app main.cpp)

# 添加测试支持
enable_testing()
add_subdirectory(tests)

在这个示例中,我们定义了一个名为 MyProject 的项目,设置了 C++ 17 标准,并且添加了一个可执行文件 my_app

1.3 持续集成流程

一个典型的持续集成流程通常包括以下步骤:

  1. 代码提交: 开发人员将代码推送到版本控制系统(如 Git)。
  2. 触发构建: CI 系统会检测到代码的变化,并开始自动构建过程。
  3. 执行测试: 构建完成后,CI 系统会运行测试。
  4. 报告结果: 测试结果会反馈给开发人员。

1.4 配置 CI 工具

常用的 CI 工具有 Travis CIGitHub ActionsGitLab CI/CD。下面以 GitHub Actions 为例,展示如何配置 CI 流程。

1.4.1 GitHub Actions 配置示例

在项目根目录下创建一个名为 .github/workflows/ci.yml 的文件,内容如下:

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
name: C++ CI

on:
push:
branches: [ main ]
pull_request:
branches: [ main ]

jobs:
build:

runs-on: ubuntu-latest

steps:
- name: Check out code
uses: actions/checkout@v2

- name: Set up CMake
uses: jwlawson/actions-setup-cmake@v1
with:
cmake-version: '3.21.2'

- name: Build
run: |
mkdir build
cd build
cmake ..
make

- name: Run tests
run: |
cd build
ctest
说明:
  • on 部分指定了事件触发条件,此处我们在 main 分支上的代码推送和拉取请求时触发 CI。
  • jobs 部分定义了 CI 的任务,这里我们设置在 ubuntu-latest 上运行。
  • steps 描述了具体执行的步骤,包括代码检出、配置 CMake、构建项目和运行测试。

1.5 运行测试

CMakeLists.txt 中添加测试,我们可以使用 CTest 来管理 C++ 测试。以下是一个简单的测试示例:

1
2
3
4
5
6
7
// tests/test_example.cpp

#include <gtest/gtest.h>

TEST(SampleTest, ExampleTest) {
EXPECT_EQ(1, 1);
}

CMakeLists.txt 中配置测试目录:

1
2
3
4
5
6
7
add_subdirectory(tests)
enable_testing()
find_package(GTest REQUIRED)
include_directories(${GTEST_INCLUDE_DIRS})
add_executable(test_example tests/test_example.cpp)
target_link_libraries(test_example GTest::GTest GTest::Main)
add_test(NAME SampleTest COMMAND test_example)

1.6 CI 结果反馈

当 CI 完成后,GitHub Actions 会将构建和测试的结果通过界面反馈给开发者。如果有任何构建失败或测试未通过,开发者可以及时修复。

1.7 结论

通过使用构建工具(如 CMake)和持续集成工具(如 GitHub Actions),我们可以有效地提高 C++ 项目的开发效率和代码质量。随着项目规模的扩大,合理的 CI/CD 流程在团队合作中显得尤为重要。

1.8 小结

在本节中,我们学习了如何使用构建工具进行持续集成,包括了 CMake 的基本使用、CI 流程的构建以及 GitHub Actions 的配置。掌握这些知识,将为你在 C++ 开发中的实战提供强有力的支持。

36 C++ 文件异常处理

36 C++ 文件异常处理

在 C++ 中,文件处理是一个常见的操作,而在进行文件读写时,处理异常是确保程序稳健的重要步骤。本节将详细介绍如何在 C++ 中处理文件异常,包括常见的错误类型和相应的处理方式。

1. 文件异常的概念

在进行文件操作时,可能会遇到各种异常情况,例如:

  • 文件不存在
  • 没有足够的权限访问文件
  • 磁盘空间不足
  • 文件已被其他程序占用

这些情况会导致程序在尝试打开或操作文件时抛出异常或设置错误状态。

2. 使用 fstream 进行文件操作

在 C++ 中,文件操作通常使用 fstream 类,它包含了读取和写入文件的基本功能。我们通常需要进行以下几个步骤:

  1. 打开文件
  2. 检查文件是否成功打开
  3. 处理文件的读写操作
  4. 关闭文件

下面的代码展示了如何打开一个文件并检查是否成功打开:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
#include <fstream>

int main() {
std::ifstream inputFile("example.txt");

// 检查文件是否成功打开
if (!inputFile.is_open()) {
std::cerr << "Error: Could not open the file!" << std::endl;
return 1; // 返回错误代码
}

// 文件操作逻辑...

inputFile.close(); // 关闭文件
return 0;
}

3. 处理异常

C++ 提供了异常处理机制,可以通过 try, catch 语句来捕获和处理异常。对于文件操作,我们可以使用自定义异常类来更好地管理错误。以下是一个示例:

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
#include <iostream>
#include <fstream>
#include <stdexcept>

void readFile(const std::string &filename) {
std::ifstream inputFile(filename);

// 检查文件是否成功打开
if (!inputFile.is_open()) {
throw std::runtime_error("Unable to open file: " + filename);
}

// 文件读操作
std::string line;
while (std::getline(inputFile, line)) {
std::cout << line << std::endl;
}

inputFile.close();
}

int main() {
try {
readFile("example.txt");
} catch (const std::runtime_error &e) {
std::cerr << "Exception: " << e.what() << std::endl;
}

return 0;
}

3.1 自定义异常类

我们还可以通过自定义异常类来处理更复杂的情况,示例如下:

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
#include <iostream>
#include <fstream>
#include <exception>

class FileException : public std::exception {
public:
FileException(const std::string &message) : msg_(message) {}
virtual const char* what() const noexcept {
return msg_.c_str();
}
private:
std::string msg_;
};

void readFile(const std::string &filename) {
std::ifstream inputFile(filename);
if (!inputFile.is_open()) {
throw FileException("Cannot open file: " + filename);
}
// ... 其他文件操作
}

int main() {
try {
readFile("example.txt");
} catch (const FileException &e) {
std::cerr << "File Exception: " << e.what() << std::endl;
}

return 0;
}

4. 结论

在 C++ 的文件处理过程中,异常处理是不可或缺的一部分。使用 trycatch 可以有效捕获并处理错误,而通过自定义异常类能够提升代码的可维护性和可读性。始终确保对文件操作中的可能出错环节进行检测,以保障程序的稳健性和可靠性。

通过本节的介绍,希望您能更好地理解 C++ 中的文件异常处理。