From 3789f373cec9b38bfc1f0aacd02ae6b9b5aa1c54 Mon Sep 17 00:00:00 2001 From: Yi Zhang Date: Fri, 16 May 2025 08:49:00 +0800 Subject: [PATCH] tmp --- doc/core/doc_str.md | 254 +++++++++++++++++++++++++++++++++++++ src/mesh/create_tin_ex.cpp | 110 ++++++++++++++++ 2 files changed, 364 insertions(+) create mode 100644 doc/core/doc_str.md create mode 100644 src/mesh/create_tin_ex.cpp diff --git a/doc/core/doc_str.md b/doc/core/doc_str.md new file mode 100644 index 0000000..910c438 --- /dev/null +++ b/doc/core/doc_str.md @@ -0,0 +1,254 @@ +# GCTL核心字符串处理模块文档(gctl/lib/core/str.h) + +## 文件概述 +```cpp +#include "exceptions.h" // 异常处理依赖 +#include // 数学函数 +#include // 向量容器 +#include // 字符串流 +``` + +本模块提供字符串与基础数据类型间的转换、字符串解析处理等核心功能,包含以下主要功能: +- 类型与字符串的相互转换 +- 字符串模式替换与路径处理 +- 带分隔符的字符串解析 +- 特殊数值(NaN/Inf)转换 +- 随机字符串生成 + +## 核心功能模块 + +### 1. 类型转换 +#### 模板函数 `type2ss` +```cpp +template +void type2ss(ObjValType in_val, std::stringstream &out_ss) +``` +- **功能**:将任意类型转换为字符串流 +- **参数**: + - `in_val`:输入值(支持基础数据类型) + - `out_ss`:输出字符串流(需预先声明) +- **示例**: + ```cpp + std::stringstream ss; + gctl::type2ss(3.14, ss); + std::cout << ss.str(); // 输出"3.14" + ``` + +#### 模板函数 `str2type` +```cpp +template +int str2type(std::string in_str, OutValType &out_val, char sep = ' ') +``` +- **功能**:带分隔符的字符串到类型转换 +- **参数**: + - `in_str`:输入字符串 + - `out_val`:输出值(引用返回) + - `sep`:分隔符(默认空格) +- **返回值**: + - 0:转换成功 + - -1:转换失败 +- **注意**:自动替换分隔符为空格后进行解析 + +### 2. 向量处理 +#### 数值向量转换 `type2str_vector` +```cpp +template +void type2str_vector(const std::vector &in_vec, + std::vector &out_vec) +``` +- **功能**:将数值向量转换为字符串向量 +- **参数**: + - `in_vec`:输入数值向量 + - `out_vec`:输出字符串向量(自动清空原有内容) + +#### 二维向量解析 `str2type_vector2d` +```cpp +// 基础版本 +template +void str2type_vector2d(...) + +// 变参模板版本 +template +void str2type_vector2d(const std::vector> &vec2d, + std::string order_str, + std::vector &vec, Args&... rest) +``` +- **新特性**: + - 支持多个输出参数,按order_str顺序解析 + - 示例:`order_str="0,2,1"` 解析第0、2、1列到不同向量 +- **异常**:统一抛出`std::runtime_error` + +#### 二维向量生成 `type2str_vector2d` +```cpp +template +void type2str_vector2d(std::vector> &vec2d, + const std::vector &vec) + +template +void type2str_vector2d(std::vector> &vec2d, + const std::vector &vec, Args&... rest) +``` +- **功能**:批量转换多个字符串向量到数值二维向量 +- **典型应用**:构建CSV格式的数据矩阵 + +### 3. 高级模板功能 +#### 变参字符串解析 `parse_string_to_value` +```cpp +template +int parse_string_to_value(std::string val_str, char separator, + bool throw_err, ValueType &fst_val, Args&... rest) +``` +- **功能**:解析含多个值的字符串到不同变量 +- **参数顺序**: + 1. 输入字符串 + 2. 分隔符 + 3. 是否抛出异常 + 4. 输出参数列表(至少1个) +- **返回值**:成功解析的参数个数 +- **示例**: + ```cpp + int a; double b; std::string c; + parse_string_to_value("5,3.14,text", ',', true, a, b, c); + ``` + +### 4. 字符串操作 +#### 全局替换 `replace_all` +```cpp +int replace_all(std::string& new_str, const std::string& old_str, + const std::string& old_value, const std::string& new_value) +``` +- **功能**:全量替换字符串中的子串 +- **参数**: + - `new_str`:替换后的新字符串(输出) + - `old_str`:原始字符串 + - `old_value`:待替换的子串 + - `new_value`:新子串 +- **返回值**:替换次数 + +#### 路径补全 `patch_string` +```cpp +std::string patch_string(std::string in_str, std::string patch_str) +``` +- **功能**:智能补全路径字符串 +- **示例**: + ```cpp + auto path = gctl::patch_string("/data", "/"); // 返回"/data/" + ``` +- **逻辑**:检查末尾是否已包含目标字符串,若否则追加 + +### 4. 特殊数值处理 +#### 安全双精度转换 `str2double` +```cpp +double str2double(std::string instr) +``` +- **功能**:转换字符串到double,支持: + - Fortran风格的科学计数法(如"1.23D+04") + - NaN/Infinity的特殊处理 +- **实现**:自动替换'D'为'E'后使用标准库转换 + +### 5. 实用工具函数 +#### 流转换函数 `str2ss` +```cpp +void str2ss(std::string in_str, std::stringstream &out_ss, std::string delimiter = "") +``` +- **功能**:将字符串转换为预处理后的字符串流 +- **参数**: + - `delimiter`:将指定分隔符替换为空格 + - `out_ss`:输出流(自动清空原有内容) +- **应用场景**:处理CSV等格式数据 + +#### 随机字符串生成 +```cpp +void random_char(unsigned int length, char* out); +void random_str(unsigned int length, std::string &out_str); +``` +- **字符范围**:a-z, A-Z, 0-9 +- **安全特性**:线程安全的随机数生成 +- **典型应用**:生成临时文件名或验证码 +- **示例**: + ```cpp + std::string random; + gctl::random_str(8, random); // 可能得到"aB3x9K7f" + ``` + +#### 通用字符串解析 `parse_string_to_vector` +```cpp +template +int parse_string_to_vector(std::string val_str, char separator, + std::vector &out_vec) +``` +- **增强特性**: + - 自动去除元素首尾空白 + - 支持保留带空格的字符串(当ValueType为std::string时) +- **示例**: + ```cpp + std::vector parts; + parse_string_to_vector("name=John Doe; age=30", ';', parts); + // 得到 ["name=John Doe", "age=30"] + ``` + +### 6. 异常处理规范 +#### 统一异常类型 +- 所有解析函数均可能抛出 `gctl::runtime_error` +- 错误信息包含: + - 具体失败位置(函数名) + - 原始输入内容片段 + - 失败原因(类型不匹配/格式错误等) + +#### 错误处理示例 +```cpp +try { + std::vector values; + gctl::str2type_vector({"1", "2.5", "abc"}, values); +} catch (const gctl::runtime_error& e) { + std::cerr << "解析错误: " << e.what(); + // 输出:解析错误: [gctl::str2type_vector] Failed to parse: abc +} + +### 7. 高级解析功能 +#### 带引号解析 `parse_string_with_quotes` +```cpp +void parse_string_with_quotes(std::string in_str, std::vector &str_vec) +``` +- **增强特性**: + - 支持嵌套引号(使用\"转义) + - 自动去除外层引号 +- **示例**: + ```cpp + 输入: `cmd "complex \"name\"" 123` + 输出: ["cmd", "complex "name"", "123"] + ``` +```cpp +void parse_string_with_quotes(std::string in_str, std::vector &str_vec) +``` +- **功能**:解析含空格和引号的字符串 +- **示例**: + ```cpp + 输入: `cmd "file name.txt" 100` + 输出: ["cmd", "file name.txt", "100"] + ``` +- **规则**: + 1. 双引号内的内容视为单个元素 + 2. 自动去除元素首尾空白 + +## 使用示例 +### 类型转换示例 +```cpp +std::vector str_vec{"1", "2.5", "3"}; +std::vector int_vec; +gctl::str2type_vector(str_vec, int_vec); // 得到[1,2,3] +``` + +### 配置文件解析 +```cpp +std::string config = "max_threads=4, timeout=30s"; +int threads; +std::string timeout; +gctl::parse_string_to_value(config, '=', true, threads, timeout); +``` + +## 注意事项 +1. **异常处理**:关键函数(如`str2type_vector`)会抛出`gctl::runtime_error` +2. **线程安全**:函数内部使用局部变量,可安全用于多线程环境 +3. **性能建议**:批量处理建议使用vector版本函数 +4. **编码要求**:输入字符串建议使用UTF-8编码 \ No newline at end of file diff --git a/src/mesh/create_tin_ex.cpp b/src/mesh/create_tin_ex.cpp new file mode 100644 index 0000000..7b48ebb --- /dev/null +++ b/src/mesh/create_tin_ex.cpp @@ -0,0 +1,110 @@ +// File: create_tin_ex.cpp +// Author: Dr. Yi Zhang (yizhang-geo@zju.edu.cn) +// Date: 2025-05-15 + +#include "gctl/io/file_io.h" +#include "gctl/io/gmsh_io.h" +#include "gctl/io/dsv_io.h" +#include "gctl/mesh/tin.h" + +using namespace gctl; + +int main(int argc, char *argv[]) try +{ + // read dem grid + std::vector topo(10201); + std::ifstream infile("data/mesh/topo"); + for (int i = 0; i < 10201; ++i) + { + infile >> topo[i]; + } + infile.close(); + + std::vector box(4); + box[0].id = 0; box[0].x = 500; box[0].y = 250; + box[1].id = 1; box[1].x = 750; box[1].y = 250; + box[2].id = 2; box[2].x = 750; box[2].y = 500; + box[3].id = 3; box[3].x = 500; box[3].y = 500; + + std::vector box_region(1); + box_region[0].set(box, 5.0); + + std::vector err_records; + std::vector tin_vert; + std::vector tin_ele; + //grd2tin(topo, 0, 1000, 0, 1000, 10, 10, tin_vert, tin_ele, 1.0, nullptr, &err_records, nullptr); + grd2tin(topo, 0, 1000, 0, 1000, 10, 10, tin_vert, tin_ele, 1.0, nullptr, &err_records, &box_region); + + int times = err_records.size(); + _1d_array errs; + errs.input(err_records); + destroy_vector(err_records); + + dsv_io log_out; + log_out.init_table(err_records.size(), 2); + log_out.column_names({"Times", "Maxi-Error"}); + log_out.fill_column(array(err_records.size(), 1, 1), "Times"); + log_out.fill_column(errs, "Maxi-Error"); + log_out.save_csv("data/mesh/topo_TIN.log"); + + // Write a Gmsh's .msh file + std::ofstream outfile("data/mesh/topo_TIN.msh"); + outfile << "$MeshFormat" << std::endl << "2.2 0 8" << std::endl << "$EndMeshFormat "<id + 1 << " " << std::setprecision(16) + << tin_vert[i]->x << " " << tin_vert[i]->y << " " << tin_vert[i]->elev << std::endl; + } + outfile<<"$EndNodes"<vert[j]->id + 1; + } + outfile << std::endl; + } + outfile << "$EndElements"<< std::endl; + outfile<<"$NodeData"<id + 1 << " " << std::setprecision(16) << tin_vert[i]->elev << std::endl; + } + outfile << "$EndNodeData" << std::endl; + outfile.close(); + + // write a neighbor file + outfile.open("data/mesh/topo_TIN.neigh"); + outfile << tin_ele.size() << std::endl; + for (int i = 0; i < tin_ele.size(); i++) + { + outfile << i + 1; + for (int j = 0; j < 3; j++) + { + if (tin_ele[i]->neigh[j] != nullptr) + { + outfile << " " << tin_ele[i]->neigh[j]->id + 1; + } + else outfile << " -1"; + } + outfile << std::endl; + } + outfile.close(); + + // Destroy memories allocated by the dem2tin function + destroy_vector(tin_vert); + destroy_vector(tin_ele); + return 0; +} +catch (std::exception &e) +{ + GCTL_ShowWhatError(e.what(), GCTL_ERROR_ERROR, 0, 0, 0); +} \ No newline at end of file