tmp
This commit is contained in:
parent
5f4d6267b6
commit
3789f373ce
254
doc/core/doc_str.md
Normal file
254
doc/core/doc_str.md
Normal file
@ -0,0 +1,254 @@
|
||||
# GCTL核心字符串处理模块文档(gctl/lib/core/str.h)
|
||||
|
||||
## 文件概述
|
||||
```cpp
|
||||
#include "exceptions.h" // 异常处理依赖
|
||||
#include <cmath> // 数学函数
|
||||
#include <vector> // 向量容器
|
||||
#include <sstream> // 字符串流
|
||||
```
|
||||
|
||||
本模块提供字符串与基础数据类型间的转换、字符串解析处理等核心功能,包含以下主要功能:
|
||||
- 类型与字符串的相互转换
|
||||
- 字符串模式替换与路径处理
|
||||
- 带分隔符的字符串解析
|
||||
- 特殊数值(NaN/Inf)转换
|
||||
- 随机字符串生成
|
||||
|
||||
## 核心功能模块
|
||||
|
||||
### 1. 类型转换
|
||||
#### 模板函数 `type2ss`
|
||||
```cpp
|
||||
template <typename ObjValType>
|
||||
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 <typename OutValType>
|
||||
int str2type(std::string in_str, OutValType &out_val, char sep = ' ')
|
||||
```
|
||||
- **功能**:带分隔符的字符串到类型转换
|
||||
- **参数**:
|
||||
- `in_str`:输入字符串
|
||||
- `out_val`:输出值(引用返回)
|
||||
- `sep`:分隔符(默认空格)
|
||||
- **返回值**:
|
||||
- 0:转换成功
|
||||
- -1:转换失败
|
||||
- **注意**:自动替换分隔符为空格后进行解析
|
||||
|
||||
### 2. 向量处理
|
||||
#### 数值向量转换 `type2str_vector`
|
||||
```cpp
|
||||
template <typename ValueType>
|
||||
void type2str_vector(const std::vector<ValueType> &in_vec,
|
||||
std::vector<std::string> &out_vec)
|
||||
```
|
||||
- **功能**:将数值向量转换为字符串向量
|
||||
- **参数**:
|
||||
- `in_vec`:输入数值向量
|
||||
- `out_vec`:输出字符串向量(自动清空原有内容)
|
||||
|
||||
#### 二维向量解析 `str2type_vector2d`
|
||||
```cpp
|
||||
// 基础版本
|
||||
template <typename ValueType>
|
||||
void str2type_vector2d(...)
|
||||
|
||||
// 变参模板版本
|
||||
template <typename ValueType, typename... Args>
|
||||
void str2type_vector2d(const std::vector<std::vector<std::string>> &vec2d,
|
||||
std::string order_str,
|
||||
std::vector<ValueType> &vec, Args&... rest)
|
||||
```
|
||||
- **新特性**:
|
||||
- 支持多个输出参数,按order_str顺序解析
|
||||
- 示例:`order_str="0,2,1"` 解析第0、2、1列到不同向量
|
||||
- **异常**:统一抛出`std::runtime_error`
|
||||
|
||||
#### 二维向量生成 `type2str_vector2d`
|
||||
```cpp
|
||||
template <typename ValueType>
|
||||
void type2str_vector2d(std::vector<std::vector<ValueType>> &vec2d,
|
||||
const std::vector<std::string> &vec)
|
||||
|
||||
template <typename ValueType, typename... Args>
|
||||
void type2str_vector2d(std::vector<std::vector<ValueType>> &vec2d,
|
||||
const std::vector<std::string> &vec, Args&... rest)
|
||||
```
|
||||
- **功能**:批量转换多个字符串向量到数值二维向量
|
||||
- **典型应用**:构建CSV格式的数据矩阵
|
||||
|
||||
### 3. 高级模板功能
|
||||
#### 变参字符串解析 `parse_string_to_value`
|
||||
```cpp
|
||||
template <typename ValueType, typename... Args>
|
||||
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 <typename ValueType>
|
||||
int parse_string_to_vector(std::string val_str, char separator,
|
||||
std::vector<ValueType> &out_vec)
|
||||
```
|
||||
- **增强特性**:
|
||||
- 自动去除元素首尾空白
|
||||
- 支持保留带空格的字符串(当ValueType为std::string时)
|
||||
- **示例**:
|
||||
```cpp
|
||||
std::vector<std::string> parts;
|
||||
parse_string_to_vector("name=John Doe; age=30", ';', parts);
|
||||
// 得到 ["name=John Doe", "age=30"]
|
||||
```
|
||||
|
||||
### 6. 异常处理规范
|
||||
#### 统一异常类型
|
||||
- 所有解析函数均可能抛出 `gctl::runtime_error`
|
||||
- 错误信息包含:
|
||||
- 具体失败位置(函数名)
|
||||
- 原始输入内容片段
|
||||
- 失败原因(类型不匹配/格式错误等)
|
||||
|
||||
#### 错误处理示例
|
||||
```cpp
|
||||
try {
|
||||
std::vector<double> 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<std::string> &str_vec)
|
||||
```
|
||||
- **增强特性**:
|
||||
- 支持嵌套引号(使用\"转义)
|
||||
- 自动去除外层引号
|
||||
- **示例**:
|
||||
```cpp
|
||||
输入: `cmd "complex \"name\"" 123`
|
||||
输出: ["cmd", "complex "name"", "123"]
|
||||
```
|
||||
```cpp
|
||||
void parse_string_with_quotes(std::string in_str, std::vector<std::string> &str_vec)
|
||||
```
|
||||
- **功能**:解析含空格和引号的字符串
|
||||
- **示例**:
|
||||
```cpp
|
||||
输入: `cmd "file name.txt" 100`
|
||||
输出: ["cmd", "file name.txt", "100"]
|
||||
```
|
||||
- **规则**:
|
||||
1. 双引号内的内容视为单个元素
|
||||
2. 自动去除元素首尾空白
|
||||
|
||||
## 使用示例
|
||||
### 类型转换示例
|
||||
```cpp
|
||||
std::vector<std::string> str_vec{"1", "2.5", "3"};
|
||||
std::vector<int> 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编码
|
110
src/mesh/create_tin_ex.cpp
Normal file
110
src/mesh/create_tin_ex.cpp
Normal file
@ -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<double> topo(10201);
|
||||
std::ifstream infile("data/mesh/topo");
|
||||
for (int i = 0; i < 10201; ++i)
|
||||
{
|
||||
infile >> topo[i];
|
||||
}
|
||||
infile.close();
|
||||
|
||||
std::vector<tin_vertex2dc> 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<region> box_region(1);
|
||||
box_region[0].set(box, 5.0);
|
||||
|
||||
std::vector<double> err_records;
|
||||
std::vector<tin_vertex2dc*> tin_vert;
|
||||
std::vector<tin_triangle*> 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<int>(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 "<<std::endl;
|
||||
outfile << "$Nodes" << std::endl << tin_vert.size() << std::endl;
|
||||
for (int i = 0; i < tin_vert.size(); i++)
|
||||
{
|
||||
outfile << tin_vert[i]->id + 1 << " " << std::setprecision(16)
|
||||
<< tin_vert[i]->x << " " << tin_vert[i]->y << " " << tin_vert[i]->elev << std::endl;
|
||||
}
|
||||
outfile<<"$EndNodes"<<std::endl;
|
||||
outfile << "$Elements" << std::endl << tin_ele.size() <<std::endl;
|
||||
for (int i = 0; i < tin_ele.size(); i++)
|
||||
{
|
||||
outfile << i + 1 << " 2 0";
|
||||
for (int j = 0; j < 3; j++)
|
||||
{
|
||||
outfile << " " << tin_ele[i]->vert[j]->id + 1;
|
||||
}
|
||||
outfile << std::endl;
|
||||
}
|
||||
outfile << "$EndElements"<< std::endl;
|
||||
outfile<<"$NodeData"<<std::endl;
|
||||
outfile<<1<<std::endl
|
||||
<<"\"Topography (m)\"" <<std::endl
|
||||
<< 1 <<std::endl<< 0.0 <<std::endl
|
||||
<< 3 <<std::endl<< 0<<std::endl
|
||||
<< 1 <<std::endl<< tin_vert.size() <<std::endl;
|
||||
for (int i = 0; i < tin_vert.size(); i++)
|
||||
{
|
||||
outfile << tin_vert[i]->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);
|
||||
}
|
Loading…
Reference in New Issue
Block a user