当前位置: 首页 > news >正文

C++.读取文件(1.5w字)

1. 基础

1.1 文件读取方式选择

在C++中,文件读取有多种方式,主要包括以下几种:

  • 逐字符读取:使用fgetc函数或ifstreamget方法,适用于需要逐字符处理文件内容的场景。
  • 逐行读取:使用fgets函数或ifstreamgetline方法,适用于按行处理文本文件,能够方便地处理包含空格的行数据。
  • 按数据类型读取:使用fscanf函数或ifstream>>运算符,适用于读取结构化数据,如按列存储的数值数据。
  • 数据块读取:使用fread函数或ifstreamread方法,适用于高效读取大量数据,如二进制文件。

选择合适的文件读取方式需要根据文件的类型和处理需求来决定。例如,对于文本文件,逐行读取通常是最方便的;而对于二进制文件,数据块读取则更为高效。

1.2 ifstream读取文本文件

ifstream是C++标准库中用于读取文件的类,提供了多种方法来读取文本文件。以下是使用ifstream读取文本文件的详细步骤和示例。

1.2.1 包含头文件

在使用ifstream之前,需要包含<fstream>头文件:

#include <fstream>

1.2.2 创建ifstream对象

创建一个ifstream对象,并指定要打开的文件名:

std::ifstream file("example.txt");

1.2.3 检查文件是否打开成功

使用is_open方法检查文件是否成功打开:

if (!file.is_open()) {std::cerr << "无法打开文件!" << std::endl;return 1;
}

1.2.4 逐行读取文件内容

使用getline方法逐行读取文件内容:

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

1.2.5 关闭文件

读取完成后,关闭文件:

file.close();

1.2.6 完整示例代码

以下是完整的示例代码,展示如何使用ifstream逐行读取文本文件:

#include <iostream>
#include <fstream>
#include <string>int main() {// 打开文件std::ifstream file("example.txt");if (!file.is_open()) {std::cerr << "无法打开文件!" << std::endl;return 1;}// 逐行读取文件内容std::string line;while (std::getline(file, line)) {std::cout << line << std::endl;}// 关闭文件file.close();return 0;
}

1.2.7 示例文件内容

假设example.txt文件的内容如下:

第一行内容
第二行内容
第三行内容

运行上述代码后,输出结果为:

第一行内容
第二行内容
第三行内容

1.2.8 Mermaid流程图

以下是使用Mermaid语法描述的ifstream读取文本文件的流程图:

开始
包含头文件
创建ifstream对象
检查文件是否打开成功
逐行读取文件内容
输出错误信息并退出
关闭文件
结束

通过上述步骤和示例代码,可以清晰地理解如何使用ifstream读取文本文件。# 2. C++读取文件进阶

2.1 ifstream读取二进制文件

在C++中,读取二进制文件需要使用ifstream类,并指定以二进制模式打开文件。以下是详细的步骤和示例。

2.1.1 包含头文件

在读取二进制文件时,需要包含<fstream>头文件:

#include <fstream>

2.1.2 以二进制模式打开文件

使用ifstream打开文件时,需要指定ios::binary模式,以确保文件以二进制方式读取:

std::ifstream file("example.dat", std::ios::binary);

2.1.3 检查文件是否打开成功

使用is_open方法检查文件是否成功打开:

if (!file.is_open()) {std::cerr << "无法打开文件!" << std::endl;return 1;
}

2.1.4 读取二进制文件内容

使用read方法读取二进制文件的内容。read方法需要指定一个缓冲区和要读取的字节数:

const int BUFFER_SIZE = 1024;
char buffer[BUFFER_SIZE];
file.read(buffer, BUFFER_SIZE);

2.1.5 检查读取状态

使用gcount方法获取实际读取的字节数:

std::streamsize bytesRead = file.gcount();
std::cout << "读取了 " << bytesRead << " 字节" << std::endl;

2.1.6 关闭文件

读取完成后,关闭文件:

file.close();

2.1.7 完整示例代码

以下是完整的示例代码,展示如何使用ifstream读取二进制文件:

#include <iostream>
#include <fstream>int main() {// 打开文件std::ifstream file("example.dat", std::ios::binary);if (!file.is_open()) {std::cerr << "无法打开文件!" << std::endl;return 1;}// 读取二进制文件内容const int BUFFER_SIZE = 1024;char buffer[BUFFER_SIZE];file.read(buffer, BUFFER_SIZE);// 检查读取状态std::streamsize bytesRead = file.gcount();std::cout << "读取了 " << bytesRead << " 字节" << std::endl;// 关闭文件file.close();return 0;
}

2.1.8 示例文件内容

假设example.dat文件是一个二进制文件,包含以下内容(以十六进制表示):

48 65 6C 6C 6F 20 57 6F 72 6C 64

运行上述代码后,输出结果为:

读取了 11 字节

2.1.9 Mermaid流程图

以下是使用Mermaid语法描述的ifstream读取二进制文件的流程图:

开始
包含头文件
以二进制模式打开文件
检查文件是否打开成功
读取二进制文件内容
输出错误信息并退出
检查读取状态
关闭文件
结束

2.2 文件读取中的异常处理

在文件读取过程中,可能会遇到各种异常情况,如文件不存在、读取错误等。C++提供了异常处理机制来处理这些情况。以下是详细的步骤和示例。

2.2.1 包含头文件

在使用异常处理时,需要包含<fstream><iostream>头文件:

#include <fstream>
#include <iostream>

2.2.2 打开文件并捕获异常

使用ifstream打开文件时,可以使用try-catch块捕获可能发生的异常:

try {std::ifstream file("example.txt");if (!file.is_open()) {throw std::runtime_error("无法打开文件!");}
} catch (const std::exception& e) {std::cerr << "异常: " << e.what() << std::endl;return 1;
}

2.2.3 读取文件内容并捕获异常

在读取文件内容时,也可以使用try-catch块捕获可能发生的异常:

try {std::string line;while (std::getline(file, line)) {std::cout << line << std::endl;}
} catch (const std::exception& e) {std::cerr << "异常: " << e.what() << std::endl;
}

2.2.4 关闭文件

无论是否发生异常,都需要确保文件被正确关闭:

file.close();

2.2.5 完整示例代码

以下是完整的示例代码,展示如何在文件读取中使用异常处理:

#include <iostream>
#include <fstream>
#include <string>int main() {try {// 打开文件std::ifstream file("example.txt");if (!file.is_open()) {throw std::runtime_error("无法打开文件!");}// 读取文件内容std::string line;while (std::getline(file, line)) {std::cout << line << std::endl;}} catch (const std::exception& e) {std::cerr << "异常: " << e.what() << std::endl;return 1;}// 关闭文件file.close();return 0;
}

2.2.6 示例文件内容

假设example.txt文件的内容如下:

第一行内容
第二行内容
第三行内容

运行上述代码后,输出结果为:

第一行内容
第二行内容
第三行内容

2.2.7 Mermaid流程图

以下是使用Mermaid语法描述的文件读取中的异常处理流程图:

开始
包含头文件 和
打开文件
是否打开成功
读取文件内容
抛出异常
是否读取成功
继续读取
捕获异常
关闭文件
捕获异常
结束

通过上述步骤和示例代码,可以清晰地理解如何在C++中读取文件并处理异常情况。

3. C++修改文件基础

3.1 文件修改方式选择

在C++中,修改文件内容有多种方式,主要包括以下几种:

  • 直接覆盖:使用ofstream以写入模式打开文件,直接覆盖原有内容。这种方式适用于需要完全替换文件内容的场景。
  • 追加内容:使用ofstream以追加模式打开文件,在文件末尾添加新内容。这种方式适用于需要在文件中追加数据的场景。
  • 随机访问修改:使用fstream以读写模式打开文件,通过定位到特定位置进行修改。这种方式适用于需要对文件中的特定部分进行修改的场景。

选择合适的文件修改方式需要根据具体需求来决定。例如,如果需要完全替换文件内容,直接覆盖是最简单的方式;如果需要在文件末尾添加内容,追加模式则更为合适;而对于需要修改文件中特定部分的情况,随机访问修改是最佳选择。

3.2 ofstream修改文本文件

ofstream是C++标准库中用于写入文件的类,提供了多种方法来修改文本文件。以下是使用ofstream修改文本文件的详细步骤和示例。

3.2.1 包含头文件

在使用ofstream之前,需要包含<fstream>头文件:

#include <fstream>

3.2.2 创建ofstream对象

创建一个ofstream对象,并指定要打开的文件名:

std::ofstream file("example.txt");

3.2.3 检查文件是否打开成功

使用is_open方法检查文件是否成功打开:

if (!file.is_open()) {std::cerr << "无法打开文件!" << std::endl;return 1;
}

3.2.4 覆盖文件内容

使用<<运算符直接覆盖文件内容:

file << "这是新的文件内容" << std::endl;

3.2.5 关闭文件

修改完成后,关闭文件:

file.close();

3.2.6 完整示例代码

以下是完整的示例代码,展示如何使用ofstream覆盖文本文件的内容:

#include <iostream>
#include <fstream>
#include <string>int main() {// 打开文件std::ofstream file("example.txt");if (!file.is_open()) {std::cerr << "无法打开文件!" << std::endl;return 1;}// 覆盖文件内容file << "这是新的文件内容" << std::endl;// 关闭文件file.close();return 0;
}

3.2.7 示例文件内容

假设example.txt文件的初始内容如下:

原始文件内容

运行上述代码后,文件内容将被覆盖为:

这是新的文件内容

3.2.8 Mermaid流程图

以下是使用Mermaid语法描述的ofstream覆盖文本文件内容的流程图:

开始
包含头文件
创建ofstream对象
检查文件是否打开成功
覆盖文件内容
输出错误信息并退出
关闭文件
结束

通过上述步骤和示例代码,可以清晰地理解如何使用ofstream覆盖文本文件的内容。

4. C++修改文件进阶

4.1 ofstream修改二进制文件

在C++中,修改二进制文件需要使用ofstream类,并指定以二进制模式打开文件。以下是详细的步骤和示例。

4.1.1 包含头文件

在修改二进制文件时,需要包含<fstream>头文件:

#include <fstream>

4.1.2 以二进制模式打开文件

使用ofstream打开文件时,需要指定ios::binary模式,以确保文件以二进制方式打开:

std::ofstream file("example.dat", std::ios::binary | std::ios::out | std::ios::in);

4.1.3 检查文件是否打开成功

使用is_open方法检查文件是否成功打开:

if (!file.is_open()) {std::cerr << "无法打开文件!" << std::endl;return 1;
}

4.1.4 定位到需要修改的位置

使用seekp方法定位到需要修改的位置。例如,定位到文件的第10个字节:

file.seekp(10);

4.1.5 修改文件内容

使用write方法修改文件内容。例如,将10个字节的数据写入文件:

char data[10] = "new data";
file.write(data, 10);

4.1.6 检查写入状态

使用good方法检查写入是否成功:

if (!file.good()) {std::cerr << "写入失败!" << std::endl;
}

4.1.7 关闭文件

修改完成后,关闭文件:

file.close();

4.1.8 完整示例代码

以下是完整的示例代码,展示如何使用ofstream修改二进制文件:

#include <iostream>
#include <fstream>int main() {// 打开文件std::ofstream file("example.dat", std::ios::binary | std::ios::out | std::ios::in);if (!file.is_open()) {std::cerr << "无法打开文件!" << std::endl;return 1;}// 定位到需要修改的位置file.seekp(10);// 修改文件内容char data[10] = "new data";file.write(data, 10);// 检查写入状态if (!file.good()) {std::cerr << "写入失败!" << std::endl;}// 关闭文件file.close();return 0;
}

4.1.9 示例文件内容

假设example.dat文件是一个二进制文件,初始内容如下(以十六进制表示):

48 65 6C 6C 6F 20 57 6F 72 6C 64

运行上述代码后,文件内容将被修改为:

48 65 6C 6C 6F 20 6E 65 77 20 64 61 74 61

4.1.10 Mermaid流程图

以下是使用Mermaid语法描述的ofstream修改二进制文件的流程图:

成功
失败
开始
包含头文件
以二进制模式打开文件
检查文件是否打开成功
定位到需要修改的位置
输出错误信息并退出
修改文件内容
检查写入状态
关闭文件
输出错误信息
结束

4.2 文件修改中的异常处理

在文件修改过程中,可能会遇到各种异常情况,如文件不存在、写入错误等。C++提供了异常处理机制来处理这些情况。以下是详细的步骤和示例。

4.2.1 包含头文件

在使用异常处理时,需要包含<fstream><iostream>头文件:

#include <fstream>
#include <iostream>

4.2.2 打开文件并捕获异常

使用ofstream打开文件时,可以使用try-catch块捕获可能发生的异常:

try {std::ofstream file("example.txt");if (!file.is_open()) {throw std::runtime_error("无法打开文件!");}
} catch (const std::exception& e) {std::cerr << "异常: " << e.what() << std::endl;return 1;
}

4.2.3 修改文件内容并捕获异常

在修改文件内容时,也可以使用try-catch块捕获可能发生的异常:

try {file << "这是新的文件内容" << std::endl;
} catch (const std::exception& e) {std::cerr << "异常: " << e.what() << std::endl;
}

4.2.4 关闭文件

无论是否发生异常,都需要确保文件被正确关闭:

file.close();

4.2.5 完整示例代码

以下是完整的示例代码,展示如何在文件修改中使用异常处理:

#include <iostream>
#include <fstream>
#include <string>int main() {try {// 打开文件std::ofstream file("example.txt");if (!file.is_open()) {throw std::runtime_error("无法打开文件!");}// 修改文件内容file << "这是新的文件内容" << std::endl;} catch (const std::exception& e) {std::cerr << "异常: " << e.what() << std::endl;return 1;}// 关闭文件file.close();return 0;
}

4.2.6 示例文件内容

假设example.txt文件的初始内容如下:

原始文件内容

运行上述代码后,文件内容将被修改为:

这是新的文件内容

4.2.7 Mermaid流程图

以下是使用Mermaid语法描述的文件修改中的异常处理流程图:

开始
包含头文件 和
打开文件
是否打开成功
修改文件内容
抛出异常
是否修改成功
关闭文件
捕获异常
结束

通过上述步骤和示例代码,可以清晰地理解如何在C++中修改文件并处理异常情况。# 5. 格式优化与代码示例

5.1 代码格式优化技巧

在C++中,良好的代码格式不仅有助于提高代码的可读性,还能减少错误,提升开发效率。以下是一些常见的代码格式优化技巧:

5.1.1 使用合适的缩进

  • 缩进方式:建议使用4个空格作为缩进单位,避免使用制表符(\t),因为不同编辑器对制表符的显示宽度可能不同。
  • 示例
#include <iostream>
#include <fstream>
#include <string>int main() {std::ifstream file("example.txt");if (!file.is_open()) {std::cerr << "无法打开文件!" << std::endl;return 1;}std::string line;while (std::getline(file, line)) {std::cout << line << std::endl;}file.close();return 0;
}

5.1.2 保持一致的命名规范

  • 变量命名:使用小驼峰命名法(camelCase),例如std::string fileName
  • 函数命名:使用小驼峰命名法,例如void readFile()
  • 常量命名:使用大写并用下划线分隔,例如const int MAX_SIZE = 1024
  • 类命名:使用大驼峰命名法(PascalCase),例如class FileProcessor

5.1.3 添加注释

  • 函数注释:在每个函数上方添加注释,说明函数的功能、参数和返回值。
  • 代码块注释:对于复杂的逻辑块,添加注释说明其作用。
  • 示例
// 读取文件内容并打印到控制台
void readFile(const std::string& fileName) {std::ifstream file(fileName);if (!file.is_open()) {std::cerr << "无法打开文件:" << fileName << std::endl;return;}std::string line;while (std::getline(file, line)) {std::cout << line << std::endl;}file.close();
}

5.1.4 使用空行分隔逻辑块

  • 逻辑块分隔:在不同的逻辑块之间添加空行,使代码结构更清晰。
  • 示例
#include <iostream>
#include <fstream>
#include <string>int main() {// 打开文件std::ifstream file("example.txt");if (!file.is_open()) {std::cerr << "无法打开文件!" << std::endl;return 1;}// 读取文件内容std::string line;while (std::getline(file, line)) {std::cout << line << std::endl;}// 关闭文件file.close();return 0;
}

5.1.5 避免过长的行

  • 行长度限制:尽量保持每行代码的长度不超过80个字符,过长的行可以适当换行。
  • 示例
std::string longString = "这是一个很长的字符串,为了保持代码的可读性,""我们将其拆分为两行。";

5.1.6 使用智能指针管理资源

  • 智能指针:使用std::unique_ptrstd::shared_ptr管理动态分配的资源,避免内存泄漏。
  • 示例
#include <memory>
#include <iostream>int main() {std::unique_ptr<int> ptr(new int(10));std::cout << *ptr << std::endl;return 0;
}

5.2 详细紧凑的代码示例

以下是一个完整的C++代码示例,展示了如何读取和修改文件内容,同时遵循上述格式优化技巧。

5.2.1 读取文件内容

#include <iostream>
#include <fstream>
#include <string>// 读取文件内容并打印到控制台
void readFile(const std::string& fileName) {std::ifstream file(fileName);if (!file.is_open()) {std::cerr << "无法打开文件:" << fileName << std::endl;return;}std::string line;while (std::getline(file, line)) {std::cout << line << std::endl;}file.close();
}int main() {// 读取文件内容readFile("example.txt");return 0;
}

5.2.2 修改文件内容

#include <iostream>
#include <fstream>
#include <string>// 修改文件内容
void modifyFile(const std::string& fileName, const std::string& newContent) {std::ofstream file(fileName, std::ios::out | std::ios::trunc);if (!file.is_open()) {std::cerr << "无法打开文件:" << fileName << std::endl;return;}file << newContent;file.close();
}int main() {// 修改文件内容modifyFile("example.txt", "这是新的文件内容\n");return 0;
}

5.2.3 读取和修改二进制文件

#include <iostream>
#include <fstream>
#include <cstring>// 读取二进制文件内容
void readBinaryFile(const std::string& fileName) {std::ifstream file(fileName, std::ios::binary);if (!file.is_open()) {std::cerr << "无法打开文件:" << fileName << std::endl;return;}const int BUFFER_SIZE = 1024;char buffer[BUFFER_SIZE];while (file.read(buffer, BUFFER_SIZE)) {std::cout << "读取了 " << file.gcount() << " 字节" << std::endl;}file.close();
}// 修改二进制文件内容
void modifyBinaryFile(const std::string& fileName) {std::fstream file(fileName, std::ios::binary | std::ios::in | std::ios::out);if (!file.is_open()) {std::cerr << "无法打开文件:" << fileName << std::endl;return;}// 定位到文件的第10个字节file.seekp(10);// 修改文件内容char data[10] = "new data";file.write(data, 10);file.close();
}int main() {// 读取二进制文件内容readBinaryFile("example.dat");// 修改二进制文件内容modifyBinaryFile("example.dat");return 0;
}

5.2.4 Mermaid流程图

以下是使用Mermaid语法描述的读取和修改文件的流程图:

成功
失败
成功
失败
开始
包含头文件
定义读取文件函数
打开文件
逐行读取文件内容
输出错误信息
关闭文件
结束
定义修改文件函数
打开文件
修改文件内容
输出错误信息
关闭文件
结束

通过上述代码示例和流程图,可以清晰地理解如何在C++中读取和修改文件内容,同时保持代码的格式优化和可读性。

6. Mermaid图辅助理解

6.1 文件读取流程图

以下是使用Mermaid语法描述的文件读取流程图,涵盖了从打开文件到关闭文件的完整过程,适用于文本文件和二进制文件的读取:

逐字符读取
逐行读取
按数据类型读取
数据块读取
开始
包含头文件
创建文件读取对象
检查文件是否打开成功
选择读取方式
使用get读取字符
使用getline读取行
使用>>读取数据
使用read读取数据块
处理读取到的字符
处理读取到的行
处理读取到的数据
处理读取到的数据块
是否继续读取
关闭文件
结束
输出错误信息并结束

6.2 文件修改流程图

以下是使用Mermaid语法描述的文件修改流程图,涵盖了从打开文件到关闭文件的完整过程,适用于文本文件和二进制文件的修改:

直接覆盖
追加内容
随机访问修改
成功
失败
开始
包含头文件
创建文件修改对象
检查文件是否打开成功
选择修改方式
使用ofstream覆盖内容
使用ofstream追加内容
使用fstream定位并修改
写入新内容
追加新内容
定位到修改位置
写入新内容
检查写入状态
关闭文件
输出错误信息
结束
输出错误信息并结束

7. 总结

在本章中,我们详细探讨了C++中读取和修改文件的方法与技巧。通过逐步拆解研究主题,从基础到进阶,深入讲解了C++文件操作的各个方面。

7.1 读取文件

7.1.1 读取方式选择

我们首先介绍了C++中读取文件的多种方式,包括逐字符读取、逐行读取、按数据类型读取和数据块读取。每种方式都适用于不同的场景,选择合适的方式可以提高代码的效率和可读性。

7.1.2 ifstream读取文本文件

通过详细的步骤和示例代码,展示了如何使用ifstream逐行读取文本文件。从包含头文件到创建对象、检查文件是否打开成功,再到逐行读取和关闭文件,每个环节都进行了详细讲解。此外,还提供了Mermaid流程图,帮助读者更好地理解整个过程。

7.1.3 ifstream读取二进制文件

进一步介绍了如何使用ifstream以二进制模式读取文件。通过read方法和gcount方法,可以高效地读取二进制文件内容,并检查读取状态。示例代码和流程图清晰地展示了整个操作过程。

7.1.4 文件读取中的异常处理

在文件读取过程中,异常处理是必不可少的。通过try-catch块,可以捕获文件打开失败、读取错误等异常情况,确保程序的健壮性。示例代码和流程图详细展示了异常处理的实现方法。

7.2 修改文件

7.2.1 修改方式选择

在C++中,修改文件内容有多种方式,包括直接覆盖、追加内容和随机访问修改。每种方式都适用于不同的场景,选择合适的方式可以满足不同的需求。

7.2.2 ofstream修改文本文件

通过详细的步骤和示例代码,展示了如何使用ofstream覆盖文本文件的内容。从包含头文件到创建对象、检查文件是否打开成功,再到覆盖内容和关闭文件,每个环节都进行了详细讲解。此外,还提供了Mermaid流程图,帮助读者更好地理解整个过程。

7.2.3 ofstream修改二进制文件

进一步介绍了如何使用ofstream以二进制模式修改文件。通过seekp方法定位到特定位置,使用write方法修改文件内容,并检查写入状态。示例代码和流程图清晰地展示了整个操作过程。

7.2.4 文件修改中的异常处理

在文件修改过程中,异常处理同样重要。通过try-catch块,可以捕获文件打开失败、写入错误等异常情况,确保程序的健壮性。示例代码和流程图详细展示了异常处理的实现方法。

7.3 格式优化与代码示例

良好的代码格式不仅有助于提高代码的可读性,还能减少错误,提升开发效率。我们介绍了使用合适缩进、保持一致的命名规范、添加注释、使用空行分隔逻辑块、避免过长的行和使用智能指针管理资源等优化技巧。通过详细紧凑的代码示例,展示了如何在实际开发中应用这些技巧。

7.4 Mermaid图辅助理解

为了帮助读者更好地理解文件读取和修改的流程,我们提供了Mermaid流程图。这些流程图涵盖了从打开文件到关闭文件的完整过程,适用于文本文件和二进制文件的读取与修改。通过直观的流程图,读者可以更清晰地理解每个步骤的作用和逻辑关系。

通过本章的学习,读者可以全面掌握C++中读取和修改文件的方法,理解不同读取和修改方式的适用场景,并学会在实际开发中应用代码格式优化技巧,提高代码质量和开发效率。

相关文章:

  • 高性能分布式消息队列系统(四)
  • OrCAD X Capture CIS设计小诀窍系列第二季--02.如何在Capture中设置元器件不输出到Netlist
  • 嵌入式基础
  • 算法性能分析
  • 资产智慧管理安全监测中心
  • 解决宝塔mysql数据库管理里的工具转换innodb提示成功但是有部分始终没有转换掉问题
  • Gradle:Gradle的下载、安装和配置环境及idea配置指南
  • C及C++编译链接过程详解
  • 旋转字符串的解题思路与算法分享
  • 二叉树-104.二叉树的最大深度-力扣(LeetCode)
  • Linux 下生成动态库时 -fPIC的作用详解
  • SpringBoot(八) --- SpringBoot原理
  • 电工基础【7】往返运动控制、星三角形降压启动
  • 深度学习N2周:构建词典
  • 【LeetCode】1061. 按字典序排列最小的等效字符串(并查集)
  • Qt 按钮类控件(Push Button 与 Radio Button)(1)
  • SLG游戏分析
  • opencv学习笔记1:图像基础、图像操作、直方图均衡化详解
  • python打卡训练营打卡记录day45
  • 【C++高阶二】STL的map和set
  • 酒店做网站/免费技能培训网
  • 扁平化网站设计趋势/网络推广怎么找客户
  • 做外贸如何选择网站/网站服务器地址查询
  • oa系统网页版/seo排名赚官网
  • 百度收录网站排名/新媒体营销六种方式
  • 蓬莱市住房和规划建设管理局网站/怎么投放广告