首页 > 系统相关 >C++_读取配置文件以及内存方式

C++_读取配置文件以及内存方式

时间:2024-09-27 10:25:31浏览次数:7  
标签:std string 配置文件 argv char C++ str 内存

开发范式

输入和输出
   程序员的另一部分时间是用在获取需求输入上
 基本上普通开发者都是业务逻辑翻译员,
   传统开发的最重要的事情就是要理解客户的需求,把需求翻译成计算机系统的流程和逻辑
 
 AI 开发是基于大模型的开
   在 AI 时代从翻译业务逻辑的程序员转变为能调教大模型的工程师
    应用开发、微调开发、专有模型开发
	从大模型知识到能力的跃迁,提高竞争力
	这个阶段遇到的主要问题是「需求模糊」或者「需求理解不一致」。

C++ 应用

对象-内存-二进制数据-序列化-反序列化
    内存中对象转换为二进制数据
	二进制数据转换为内存中的对
		
memcpy() 从源头指向的内存块拷贝固定字节数的数据到目标指向的内存块.
与strcpy()函数不同的是,该函数不会检查任何终止字符(如'\0'),而总是精确的拷贝参数传入的字节数	

   memcpy()函数拷贝结构体数据
    用循环的方式将字节内容逐一拷贝,直到达到要求的字节数为止.

-B <path> 或 --build <path>: 
指定构建目录,也就是生成的 Makefile 或其他构建系统文件将被放置的地方,
以及最终二进制文件将被编译到的位置。
如果指定的目录不存在,CMake 会创建它。

C++ 编程起始

int main(int argc,char* argv[]) 也可以写成 int main(int argc,char** argv)
int main(int argc,char* argv[]) 也可以写成 int main(int argc,char** argv)。
     argc 表示程序运行时发送给main函数的命令行参数的个数(包括可执行程序以及传参)。
     argv[]是字符指针数组,它的每个元素都是字符指针,指向命令行中每个参数的第一个字符。
     
     argv[0]指向可执行程序。
     argv[1]指向可执行程序后的第一个字符串。
     argv[2]指向可执行程序后的第二个字符串 。
     argv[3]指向可执行程序后的第三个字符串 。
     argv[argc]为NULL。
--表现形式和内容本质
    char* argv[]和char** argv的声明差异,从声明、内存管理和文件作用域
    声明差异-语法
         char* argv[]声明一个数组argv,该数组保存多个指向char类型的指针
         char **argv声明 argv为指向(指向 char 类型的指针)的指针
        换句话说,一个是数组类型的声明,一个是指针类型的声明
    从内存管理的角度分析
       在声明数组的时候,会在内存中分配连续的数组空间
       在分配指针的时候,不会分配上述空间
    从函数传参
        对于函数传参,这两种方式的运行结果是相同的
		
	指针数组:用于存储指针的数组
	   char* argv[]来说,首先结合的时argv[]数组,这个数组中的数据类项是 char*, 因此是指针数组
	   char (*p)[5]首先结合的是(*p),这是个指针,指向的是个数组,因此是数组指针
	   *argv 是数组中第一个元素相当于line[0],argv[n]就相当于line[n],即地址一个指针,
	   **argv  是数组中存储的指针所指向的元素,即具体的字符。

C++内存模型

全局/静态存储区:全局变量、静态变量分配在这里。
常量存储区:存储常量字符串
堆内存:动态分配的内存 。 std::shared_ptr 自动管理内存 / 在堆上动态分配对象
栈内存:用于局部变量、函数参数等,通过栈指针自动管理。

静态成员为所有类对象所共享,不属于某个具体的对象,存放在静态区。  
  static 被引入以告知编译器,将变量存储在程序的静态存储区而非栈上空间,
   静态数据成员按定义出现的先后顺序依次初始化  -静态成员变量一定要在类外进行初始化

函数

 c++实现字符串分割split()函数: stringstream类是<sstream>头文件中定义的流之
	用非空白符做分割, getline()函数
	getline()是 C++标准库中的一个函数,用于从输入流中读取一行文本,并将其存储为字符串 直到遇到换行符 ('\n') 为止  
	 is 是输入流对象(通常是 std::cin)。str 是用于存储读取内容的字符串对象。
	  getline 还有一个变体,可以指定自定义的分隔符:
	  getline(istream &__is, string &__str, *char* __delim)
	  
// 例2.将字符串"hello,world,!,My,name,is,C++"按','分割。(非空白符)
 std::string str_dat = "hello,world,!,My,name,is,C++";
 std::string t;
 stringstream ss(str_dat);
 vector<string> res;
 while (ss.good()){
    getline(ss, t, ',');
    res.push_back(t);
 }
    
 for (auto i : res)
     cout << i << endl;	  

 因为stringstream继承自iostream,所以所有支持<<和>>操作的类型(包括自定义的类)都可以利用stringstream进行转换	
 
 优化容器操作:
   在容器(如 std::vector、std::list 等)中,使用 std::move 可以优化元素的插入和赋值操作。
     例如,当向 std::vector 插入一个大型对象时,使用移动构造函数可以避免不必要的复制
  emplace_back 函数用于在容器的末尾就地构造一个新元素。它避免了额外的复制或移动操作,因为它直接在容器的内存中构造元素。
    emplace_back 可以接受任意数量和类型的参数,这些参数将被转发给新元素的构造函数
	getline(ss,t,",");
	res.emplace_back(std::move(t));
2.分割符为多个字符时

创建文件夹

1.命令行的方式  方法一: system 函数   方法二: popen 函数
示例

  std::string cmd("mkdir -p /data/example");
  int ret = system(cmd.c_str());)
语法解释:
 0.int system( const char *command )
 01.std::string scmd("Initial string");  //根据已有字符串构造新的string实例
    std::string s1;             //构造一个默认为空的string
    std::string s2 (s0);         //通过复制一个string构造一个新的string
    std::string s3 (s0, 8, 3);    //通过复制一个string的一部分来构造一个新的string。8为起始位置,3为偏移量。
	std::string s7 (s0.begin(), s0.begin()+7);  //通过迭代器来指定复制s0的一部分,来创建s7

 02.c_str() 函数可以将 const string* 类型 转化为 const char* 类型
  头文件:#include<cstring>      
  在c语言中没有string类型,故必须通过string类对象的成员函数c_str()把string 对象转换成c中的字符串样式。
  C++ 中 c_str()就是将C++的string转化为C的字符串数组,
     c_str()生成一个const char *指针,指向字符串的首地址
	 
2.
 在C++中(c++17 以上),
 <filesystem> 头文件中的std::filesystem::exists() 函数来检查文件是否存在

  01. std::experimental::filesystem::exists() 查找文件是否存在
  02. std::experimental::filesystem::is_directory() 判断是否是一个目录
  03. std::experimental::filesystem::create_directory() 单层级目录创建
  0   std::experimental::filesystem::create_directories 多层级目录创建
 早期 C++ 版本中的std::experimental::filesystem是在 C++17 之前的一个技术规范
       std::filesystem  C++17的技术规范

读取配置文件

   fstream又细分了两个分支,分别是处理输入文件流的ifstream和处理输出文件流的ofstream。
        ifstream负责将文件从硬盘读取至内存中。
        ofstream负责将文件从内存写入硬盘中。
    // 以二进制模式打开文件
   std::ifstream file("example.bin", std::ios::binary | std::ios::ate);
   // std::ios::ate 定位到文件末尾,便于获取文件大小
     #include <fstream>
     #include <iostream>
     #include <string>
      
     int main() {
         std::string line;
         std::ifstream file("example.txt"); // 打开文本文件
         if (file.is_open()) {
             while (getline(file, line)) { // 按行读取
                 std::cout << line << '\n';
             }
             file.close();
         } else {
             std::cout << "Unable to open file";
         }
         return 0;
     }	   
   
读取配置文件 
  json 
  yaml
1.读取json 
    #include<jsoncpp/json/json.h>
Json::Reader reader;
Json::Value  cfg_value;	

std::ifstream input_file(cfg_path.c_str()); // 打开文本文件
if (input_file.is_open()) { exit(-1)}
input_file >> cfg_value;
input_file.close();
//当json对象里有多个子对象,想要取出其子对象时可用函数getMemberNames(),
//其返回值是Json::Value::Members类型,其实是一个标准的std::vector<string>类型:

for(const auto &key:cfg_value.getMemberNames() ){
  std::string name = cfg_value[key].asString();
 }

Json::Value::Members members = cfg_value["role"].getMemberNames()
// 解析完成,开始访问JSON对象	

std::string name = cfg_value["name"].asString();

/////.jsoncpp写json
Json::Value root; //根节点
//编写root
root["project"] = "classify";
root["base_params"]["height"] = 480;

// 创建json 文件
	fstream f;
	f.open ("test.json", ios::out);
	if( !f.is_open() ){
   		 cout<< "Open file error!" <<endl;
	}
	
f << root.toStyledString(); //转换为json格式并存到文件流
f.close();

读取yaml

#include "yaml-cpp/yaml.h"	
// 加载YAML文件	
YAML::Node params = YAML::LoadFile(cfg_path.c_str());	
// 获取对应的值
std::string file_nm = params["file_nm"].as<std::string>();

基础示例

#include <iostream>
#include <string>
 
int main() {
    std::string str = "Hello, World!";
    size_t pos1 = 1; 
    size_t pos2 = 10; 

    // 手动交换字符
    char temp = str[pos1];
    str[pos1] = str[pos2];
    str[pos2] = temp;
	// 展示结果
    std::cout << str << std::endl; // 输出: Hello, dlroW!
    return 0;
}	

参考

c++实现字符串分割split()函数(实用,详细)https://zhuanlan.zhihu.com/p/660791531		

标签:std,string,配置文件,argv,char,C++,str,内存
From: https://www.cnblogs.com/ytwang/p/18435160

相关文章

  • 广州C++信奥老师解1913:【00NOIP普及组】单词接龙
    ​ 【题目描述】 【输出】 样例连成的“龙”为atoucheatactactouchoose#include<bits/stdc++.h>usingnamespacestd;intv[21],ans=0,n;stringa[21];intgetPos(strings1,strings2)//beast和astonish例ast则返回位置2,但实际把后面onish接上去{for......
  • 动态内存管理
    目录1.为什么会有动态内存管理2.malloc和free2.1  malloc2.2  free3.calloc和realloc3.1  calloc3.2  realloc4.常见的动态内存的错误                                     ......
  • Open3D 点云分割之最小图割算法(C++)
    文章目录一、原理概述1.1基本原理1.2最小割算法二、实现代码三、实现代码参考资料一、原理概述1.1基本原理(1)首先用一个无向图G=<V,E>来表示要分割的点云,V和E分别是顶点和边的集合(构建无向图),其中每条边均有着相应的权重。不同于普通的图结构,GraphCuts图......
  • 织梦CMS的数据库配置文件 data/common.inc.php
    打开数据库配置文件:使用FTP客户端或服务器文件管理器打开织梦CMS的数据库配置文件 data/common.inc.php。检查配置信息:查看 $dbip、$dbport、$dbuser、$dbpwd 和 $dbname 这些变量的值是否正确。验证数据库连接:使用数据库管理工具登录数据库,验证提供的数据......
  • 在 VS Code 中配置 C/C++ 开发环境(详细指南)
    前言VisualStudioCode(VSCode)是一个广泛使用的代码编辑器,支持多种编程语言,包括C和C++。本指南将详细介绍如何在VSCode中设置C/C++开发环境,适合新手。1.安装编译器1.1.Windows系统推荐使用MinGW-w64:下载MinGW-w64访问MinGW-w64官网。选择适合你系统......
  • 每天学点C++之引用
    一概述请大家先看一段代码:#include<iostream>usingnamespacestd;intmain(){ inta=3; int&b=a; cout<<&b<<endl; cout<<&a<<endl; b=4; cout<<a<<endl; cout<<b<<endl; ret......
  • C++实现一个配置系统
    开发环境Qt6& boost目标通过模板的匹配方式,实现key-value的配置读取方式,value支持基本类型及自定义类型。实现通过重载类型转换类Transformer实现多种类型的和QString的转换#include<QString>#include<QJsonDocument>#include<QJsonObject>#include<QJsonArray>......
  • 【C++习题】2.双指针_移动零
    文章目录题目链接:题目描述:解法(快排的思想:数组划分区间-数组分两块):C++算法代码:图解题目链接:283.移动零题目描述:解法(快排的思想:数组划分区间-数组分两块):双指针算法,利用数组下标充当指针。我们可以用一个cur指针来扫描整个数组,另一个dest指针用来记......
  • 【Py/Java/C++三种语言OD独家2024E卷真题】20天拿下华为OD笔试之【哈希表】2024E-选修
    可上欧弟OJ系统练习华子OD、大厂真题绿色聊天软件戳oj1441了解算法冲刺训练(备注【CSDN】否则不通过)文章目录相关推荐阅读题目描述与示例题目描述输入输出示例一输入输出说明示例二输入输出说明解题思路代码pythonjavacpp时空复......
  • 【Py/Java/C++三种语言OD独家2024E卷真题】20天拿下华为OD笔试之【DFS/BFS】2024E-开
    可上欧弟OJ系统练习华子OD、大厂真题绿色聊天软件戳oj1441了解算法冲刺训练(备注【CSDN】否则不通过)文章目录相关推荐阅读题目描述与示例题目描述输入输出示例一输入输出说明示例二输入输出解题思路代码解法一:BFSpythonjavacpp......