C++相关
文章平均质量分 57
时光清浅,不觉多年
凡是过往,皆为序章。
展开
-
构造函数不支持多态
今天在写项目的时候,需要使用到多态的效果,因此就设计了三个类,一个基类,一个派生类,外加一个派生类中需要使用到的界面类。大体结构如下:///< 基类 >// 头文件#pragma once#include <QtWidgets/QMainWindow>#include "ui_wgttest.h"class QTabWidget;class WgtTest : public QMainWindow{ Q_OBJECTpublic: Wgt原创 2021-08-28 09:16:01 · 317 阅读 · 0 评论 -
C++和Qt的方式判断IP地址是否合法
在接触的项目中,遇到了需要判断IP地址是否合法的需求,用纯C++和Qt的方式,分别写了一种,如下所示。Qt的方式:bool ipAddrIsOK(const QString & ip){ if (ip.isEmpty()) { return false; } QStringList list = ip.split('.'); if (list.size() != 4) { return false; } for (const auto& num : list原创 2021-08-12 11:47:01 · 2408 阅读 · 1 评论 -
VS中bool值为true(205)的解决方法
今天在调试代码的时候,发现一个bool值判断式的返回值一直有问题,明明两个值都是true,但是判断的返回值却是false,一直进不了期望的分支。if (m_active == active){ // do sth.}else{ // do sth.}后面打断点跟踪,发现其中一个值为true(205),另一个值是true,没有下标,如下图所示:这让我很困惑,查了资料之后发现,这与VS本身的初始化值有关系:当一个函数的参数返回值是bool的时候,如果将这个函数表达式直接作为参数传递给原创 2021-08-10 18:22:25 · 1106 阅读 · 0 评论 -
使用C++进行字符串转数字注意点
为了操作方便起见,我在项目中使用到的转换函数是C++中string自带的诸如stoi等的转换函数,而不是C风格的ctoi等方法,但是使用这些方法需要几个注意点:1. 字符串不能为空;2. 字符串中不能有特殊字符。这两点对于字符串转为数字而言非常重要,这也就对代码提出了一些要求:1. 转换之前先判空;2. 判断是否有特殊字符。鉴于此,特意写了一个判断函数,源码如下:bool strIsOK(const std::string & rawData) const{ auto iter =原创 2021-08-09 11:43:14 · 299 阅读 · 0 评论 -
更改浮点型数据显示小数位数的方法
因工作需要,需要将float类型的数据通过字符串的方式进行展示。在使用to_string()函数进行转换的过程中,出现了一点问题,因为精度丢失的问题,某些情况下数据的展示不正常,例如某个数据位-180,但是在通过to_string()进行转换之后,就变成了如下图所示的样子:鉴于此,在查阅了相关的资料之后,将相关的解决方法展示如下。方法一:使用"setprecision"+"字符流"的方式在查阅资料的过程中,首先映入眼帘的是就是通过C++中的setprecision的方式修改显示的精度。但是查阅到原创 2021-07-09 18:12:08 · 2142 阅读 · 0 评论 -
教训:接收缓冲区一定要记得清空
有一个需求是需要程序获得本机的ip配置,因此采用的方式是通过C++代码调用ipconfig的方式获得。在网上查阅了相关的资料之后,最终选择采用调用CreateProcess的方式获取。部分代码如下:string getIpconfigCommandResult(){ string command("ipconfig"); unsigned len = command.size() * 2; setlocale(LC_CTYPE, ""); wchar_t *p = new wchar_t[l原创 2021-05-19 14:30:29 · 563 阅读 · 0 评论 -
正则表达式简述
注:本文仅用于介绍正则表达式中的基本概念和语法。正则表达式:Regular Expression所以在Qt中如果想要使用正则表达式,需要包含头文件QRegExp,在C++中使用正则表达式的话,需要包含的头文件是regex。正则表达式,顾名思义,是一种符合正确规则的表达式,里面重要的点在于 “正确” ,也就是符合期望,它是一种字符串匹配的模式。1. 表现形式正则表达式的表现形式是一串字符串,在这串字符串中包含了我们希望能够正确匹配的规则。2. 字符分类字符分为两类:普通字符、特殊字符(元字符)原创 2021-05-14 15:35:59 · 261 阅读 · 0 评论 -
C++中使用lua脚本
还是因为项目的原因,需要在C++中使用到lua脚本,使用到的就是普通的lua库,可以在这里下载。1. 项目中导入lua模块创建工程后,在项目中导入lua模块,一个是lua的头文件,还有就是lua的lib库关于lib库,比较简单的使用方式就是直接使用这个以-static结尾的静态库即可,比较方便,无需其他操作。2. 使用先创建一个lua脚本,比较简单,就定义了一个字符串、一个表格、两个函数(一个有参,一个无参)。如下:mystr = "I'm lua"myTable = {name = "原创 2021-04-22 19:51:53 · 5519 阅读 · 3 评论 -
使用socket进行网络通信时候的注意点(内存分配即初始化的方式控制库的加载和卸载)
以使用socket进行UDP通信为例,在通信开始和结束的时候,分别会调用库函数加载和卸载的操作,一般情况下,比较简略的代码是直接在调用数据通信之前加载库,以及在结束通信之后卸载库,也就是调用WSaStartup和WSACleanup函数。WSAStartup:通知操作系统,启用SOCKET的DLL库WSACleanup:WSACleanup()是一个计算机函数,功能是终止Winsock 2 DLL (Ws2_32.dll)的使用,函数原型是int PASCAL FAR WSACleanup (v原创 2021-04-16 15:18:20 · 318 阅读 · 0 评论 -
C++实现字符串去掉前后的空格
今天遇到一个需求,需要去除字符串前后的空格,因为std::string本身没有去除空格的函数,因此自己写了一个,如下:string trimmed(const string & data){ int lPos = data.find_first_not_of(' '); int rPos = data.find_last_not_of(' '); return data.substr(lPos, rPos - lPos + 1);}比较简单,仅仅是记录一下。...原创 2021-04-14 10:18:13 · 1383 阅读 · 0 评论 -
C++中使用MySQL数据库
文章目录1. 安装MySQL2. 拷贝include和lib文件夹到C++工程中3. 正式使用数据库3.1 范例3.2 类介绍3.2.1 MYSQL句柄类3.2.2 MYSQL_RES查询结果集3.2.3 MYSQL_ROW获取单行内容3.3 重要接口函数介绍3.3.1 连接数据库3.3.2 查询3.3.3 获取查询结果集3.3.4 读取结果集数据4. 结果演示参考链接因为项目需要使用C++的方式调用MySQL数据库,因为以前使用的都是Qt的数据库类,因此在网上查阅相关资料后,特整理一下使用方法。(下方的原创 2021-04-09 10:29:45 · 22530 阅读 · 6 评论 -
C++中使用json
文章目录1. 项目中导入rapidjson模块2. 使用2.1 写json数据2.2 读json3. 总结参考链接因为项目的原因,需要在代码中读写json格式的数据。又因为不是采用的Qt,所以不能直接使用Qt的json读写,因此选择了第三方库rapidjson。关于json的语法,可以查阅我的另一篇博客json介绍及使用QJson操作json格式数据,这里面对于json的语法以及Qt对于json格式数据的操作进行了比较详细的介绍。rapidjson仅仅是生成/解析json格式的数据,并不涉及到具体的文原创 2021-04-07 13:56:04 · 6595 阅读 · 0 评论 -
C++代码中调用Python处理脚本的方式
文章目录前言(背景介绍)一:环境配置1. 安装Python2. 创建C++项目3. 拷贝文件夹4. 在VS中配置Python内容5. 将py文件拷贝到可执行程序目录下二:代码中调用py文件1. 初始化2. 导入python脚本模块3. 函数调用3.1 无参函数调用3.2 有参函数调用4. 结果演示参考链接前言(背景介绍)因为项目中需要使用到Python脚本,而主代码是用C++书写的,因此需要实现C++调用Python。因为此篇文章主要起测试连接作用,因此使用比较简单,下方为Python脚本内容:#原创 2021-03-30 16:20:51 · 1553 阅读 · 3 评论 -
Python中创建十六进制数组的方式
项目中使用到Python脚本进行边缘计算,其中有一个需求在测试的时候需要使用到十六进制的数据,在查阅资料之后决定使用bytearray的fromhex函数,示例代码如下:def dealWithArray(bytes): if len(bytes) < 100: return '' else: mode = bytes[10] if mode == 0: return 'RESET' elif mode == 1: return 'STOP' elif mode原创 2021-03-29 17:49:57 · 3218 阅读 · 1 评论 -
installshield的一些高级操作(环境变量、软件调用等)
这篇博客是对于installshield使用的补充,主要介绍在installshield中如何进行一些高级设置。文章目录1. 环境变量1.1 Installshield中环境变量的相关参数1.2 常用的环境变量1.3 使用bat脚本设置环境变量2. 安装附加操作2.1 Installshield中的事件2.2 安装结束之后调用某个EXE文件的方式参考链接1. 环境变量1.1 Installshield中环境变量的相关参数Value: 添加的值On Install:Set:已经存在的环境变量原创 2021-02-25 10:29:59 · 1997 阅读 · 0 评论 -
数据库报duplicate XXX entry for key primary错误的可能原因以及解决方法
今天在使用数据库的过程中,发现一直报duplicate entry for key primary的错误,如下图所示:这个问题直译过来就是主键设置重复,或者说是主键冲突,因为第一次碰到这样的问题,有些不明所以,就在网上差了一些资料,发现了这么一篇文章 ======> 这是文章链接其中说到这种情况的可能原因有两种:主键没有设置自增插入线程频率较高,没有处理好事务,造成插入sql执行顺序混乱该文章中也给予了对应的解决方案,可以参考。不过这篇文章中所说到的情况并不适应于我今天遇到的问题原创 2021-02-23 14:23:24 · 95066 阅读 · 2 评论 -
VS工程中的一些概念以及常用属性设置
这里面主要介绍一下VS工程中属性的相关配置,因为是第一次写,可能有些简略。(这里面只是列出了目前为止我认为比较重要的信息)1. 宏值介绍$(SolutionDir) — 解决方案目录$(Platform) — 平台目录(x86/x64)$(Configuration) — 编译模式(Debug/Release)$(ProjectDir) — project所在的目录$(ProjectName) — 具体的project 名称,例如一个解决方案下,每一个工程都有各自的名称原创 2021-02-20 14:56:55 · 637 阅读 · 1 评论 -
C++中“流”的理解
文章目录前言我理解的“流”使用“流”的优势C++中“流”的分类参考链接前言关于流本质的问题,其实从我刚开始学习C++的时候,就已经存在了。当时找了不少的资料,不过一直处于那种知其然而不知其所以然的状态,关于流的本质问题我还是一直没有搞通,始终就是懵懵懂懂的。不过在今天,我在一时兴起又在查阅流相关资料的时候,突然发现我貌似能够理解了它,因此用此篇博客来记录一下。有一点需要事先声明一下,以下的内容,皆是我自己的理解,由于个人知识积累及阅历的原因,可能会存在一些不足,如果发现有错误,还请读者予以斧正。我原创 2021-02-18 11:06:19 · 1790 阅读 · 2 评论 -
C++中字符串和数字的相互转化
数字→字符串:to_string()字符串→整型:stoi()to_string()在转化浮点型数据的时候默认精度为6(小数点后保留6位小数),鉴于此未找到可以控制位数的函数,如果有需要,可以自己写一个。string str1("123456");cout << stoi(str1) << endl;int iNum = 666;double dd = 123.4;cout << to_string(iNum) << ends <<原创 2021-01-26 15:21:40 · 408 阅读 · 2 评论 -
VS编译器在调试的时候添加参数agrv的方式
最近做的项目涉及到在软件启动的时候需要参数,但是一开始我不知道怎么在VS中添加参数,采取的方法就是通过cmd调用编译之后的版本,这种方法不仅麻烦而且没法调试。后面经过我经理的提醒,可以在VS中添加调试需要的参数,如下:右键项目属性,在“调试”中选择“命令参数”,输入需要的参数即可。...原创 2021-01-26 14:00:28 · 755 阅读 · 0 评论 -
C++对于文件的操作(4)——更改文件指定位置的数据(在新旧数据长度不一致的情况下)
上篇博客说到了在“新旧长度一致”的情况下如何更改文件制定位置的数据,这一篇就来说明一下如何在新旧长度不一致的情况下更改文件中某一行的数据。具体的思路主要是:遍历行→保存行→更改指定行→保存后面的行→重写文件。简而言之,找到需要修改的行,然后修改之,保存前面的数据,保存后面的数据,重写即可。示例代码如下:void modifyFile(const string & fileName){ if (!fileName.empty()) { fstream file(fileName, i原创 2021-01-26 13:48:45 · 917 阅读 · 1 评论 -
C++对于文件的操作(3)——更改文件指定位置的数据(在新旧数据长度一致的情况下)
如果需要对于文件的某一个位置(或者是某一段位置)进行修改(前提是大小长度一致,这点一定要注意),一个可行的方法就是定位到需要改的地方,然后直接替换,然后重写这段数据。这里面需要用到的就是定位函数,和瞬移函数(`・ω・´),主要是tellg,tellp,seekg, seekp,这四个函数的具体的使用详见文章末尾的参考链接,这里只简单进行说明一下,tellg和tellp是用来获得文件句柄额当前位置的,而seekp、seekg是将文件句柄跳跃到具体的位置的。ifstream 类和 fstream 类有 s原创 2021-01-26 12:21:35 · 1730 阅读 · 0 评论 -
C++对于文件的操作(2)—— 使用istringstream实现split功能
因为这个软件的功能涉及到字符串的切割并重组,不过因为string中没有split函数,因此就想自己写一个字符串分割函数。在网上查阅了相关的资料之后,发现istringstream流可以实现这个功能。istringstream流可以绑定任意的string字符串,并且可以像fstring似的把被操作的对象当成一个“流”进行处理,并且istringstream有一个getLine函数的重载函数,可以实现对于指定分隔符的分割操作。注意,在使用istringstream之前,需要包含他的头文件sstream,代原创 2021-01-26 11:48:50 · 371 阅读 · 0 评论 -
C++对于文件的操作(1)—— 使用fstream执行对于文件的读写操作
以前读写文件一般使用的是Qt的QFile类,不过这次因为这个软件需要比较小巧,使用Qt就不算方便了,因为使用Qt的话,在打包的时候会链接上各种东西。因此,最后决定直接使用C++的fstream类进行读写(至于为什么不适用C的方式,主要原因在于C++在这方面控制的要比C好)。示例代码如下:void readFile(const string& fileName){ fstream file(fileName, ios::in); if (!file.is_open()) { ce原创 2021-01-26 11:21:39 · 471 阅读 · 0 评论 -
关于Qt和C++中对于线程的控制权不同的处理方式
今天一个bug花了很大的精力才确定的位置,这个bug的起因在于主线程是用纯C++写的,但是集成的子线程却是使用Qt的QThread类写的,这就导致如果不进行特殊处理的话,C++写的主线程无法获得子线程的控制权。这就导致主线程跑主线程的,子线程跑子线程的,造成应用程序退出的时候,子线程的退出清理逻辑没法执行完,然后进程就结束了,分配给子线程的资源也已经被回收了,这就很烦。我在子线程的清理逻辑中加了一个关闭数据库的操作,现在的情况就是程序退出,数据库关闭指令没法执行!!!然后一怒之下,我就去查了查C++和原创 2020-12-17 17:06:17 · 390 阅读 · 1 评论 -
各种数据库的查询结果限制条数的SQL语法
MySQLMySQL数据库中提供了limit关键字用来限制返回的结果集,语法为“Limit 需要返回记录的首行行数,要返回记录的条数”,例如:SELECT * FROM T_EMPLOYEE ORDER BY EMPLOYEE_ID LIMIT 10,5查询结果就是5行数据,从第10行开始。SQLServer2000微软SQL Server2000提供了TOP关键字用来返回结果集中的前N条记录,语法为“SELECT TOP 条数 字段列表 FROM 表名”。例如:SELECT TOP 10 *原创 2020-12-09 15:33:16 · 5232 阅读 · 0 评论 -
一种在VS中为项目添加“宏定义”的方式
今天发现项目中缺少了一个宏定义“WITH_MYSQL”,然后我就很low地在代码中使用#define WITH_MYSQL进行添加了这个宏值。然后我同事看到了,就说,对于这种宏值,最好不要在代码中添加,可以通过在项目属性中进行添加,过程如下:1.右键项目,点击属性,跳出如下界面,然后选中C/C++→预处理器,界面如下:2.选择“预处理器定义”,点击右边进行编辑:3.在编辑框中添加“WITH_MYSQL”宏值即可:顿时就高端大气上档次了,有没有!...原创 2020-12-02 15:07:48 · 2758 阅读 · 0 评论 -
一种对于数据库而言更方便地不重复建表的方式
前面提到过对于sqlite如何判断表格是否已经存在的方式,现在有了一种针对MySQL更方便的不重复建表的方法,使用not exists,代码如下:CREATE TABLE IF NOT EXISTS device_info( id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, #主键 type_value VARCHAR(1024), #数据值 );使用本种方式即可达到不重复建表的目的。...原创 2020-12-01 15:25:55 · 215 阅读 · 0 评论 -
关于mutex的try_lock函数使用的注意点
对于mutex的普通上锁解锁而言,有三个函数:lock、try_lock、unlock。这三个函数的原型如下: void lock() { // lock the mutex _Mtx_lockX(_Mymtx()); } bool try_lock() { // try to lock the mutex return (_Mtx_trylockX(_Mymtx()) == _Thrd_success); } void unlock() { // unlock th原创 2020-11-28 16:34:39 · 6525 阅读 · 0 评论 -
结构化文档与XML基本概念介绍
文章目录结构化文档XML1.声明 declaration2.元素 element3.属性 attribute4.实体 —— 具有特殊含义的字符5.注释6.总结结构化文档结构化文档由标题、章节、段落等逻辑结构组成。“结构化”听起来太抽象了,实际上结构化就是为文档建立一个框架,就象写文章先写一个提纲。结构化使你的文档看起来不会杂乱无章,每一部分都紧密联系,形成一个整体。结构化有两个原则:每一部分(每一个元素)都和其他元素有关联,关联的级数就形成了结构。标识本身的含义与它描述的信息相分离。XML原创 2020-11-16 14:36:27 · 2557 阅读 · 0 评论 -
一种VS设置中文编码格式的方式
1.选中文件之后点击“文件”2.选中“高级保存选项”3.编码格式改为“Unicode(UTF-8无签名)”原创 2020-11-10 09:02:38 · 786 阅读 · 0 评论 -
.h .lib .dll文件的关系和区别
三者含义.h:头文件 —— 编译时需要.lib:静态链接库/动态链接库的导入库 —— 链接时需要.dll:动态链接库 —— 运行时需要三者关系:.h:声明函数接口.dll:函数可执行代码.lib:因为.lib有两个身份,分开讨论如果作为动态链接库的导入库:告诉编译器,调用的函数在哪个dll文件中 —— 起到“桥梁”的作用。如果作为静态链接库:函数的可执行代码也集成在其中。导入库和静态库虽然都是以.lib作为结尾的,但是他们的区别很大,他们实质是不一样的东西。静态库本身就包含了实际执原创 2020-11-03 17:37:35 · 907 阅读 · 0 评论 -
使用installsheild进行软件打包的步骤及注意项
今天早上,完成了我人生中第一次完整意义上的软件打包,现在整理一下步骤:新建文件,因为我需要的是msi格式的软件包,因此选择情况如下:添加软件信息,如公司名、软件名、版本号、公司地网站地址等:设置系统环境,此软件我选择的是默认:设置软件文档结构,把软件中的结构添加进来:设置快捷方式:设置支持语言:添加依赖库,按照步骤一点点进行:开始构建项目:以上就是简单的步骤,需要注意的是,如果软件需要加密,那么最好的方式是对其中的关键文件进行加密,如依赖的动态库、.ex原创 2020-10-22 09:18:09 · 1298 阅读 · 0 评论 -
关于任意个数参数的实现方式
对于一个给定的函数而言,参数的个数个类型都是确定的,如果在某些情况下想要是实现参数个数任意应该怎么处理呢?分为两种情况:参数类型一致参数类型不定对于参数类型一致的情况,可以采用Initializer_list的方式来实现,示例代码如下:void print(std::initializer_list<int> vals){ for (auto it=vals.begin(); it!=vals.end(); ++it) { std::cout << *it &原创 2020-10-20 19:11:48 · 773 阅读 · 0 评论 -
关于统一格式的初始化方式
使用{}进行初始化工作,在格式上更加整齐。编译器在看到{}出现的时候,会做出一个initialzer_list(内部关联到一个array),使用{}的时候实际上是使用initialzer_list进行初始化工作。如:int values[]{1,2,3,4,5,6};//initialzer_list<int>();vector<int> v{2,4,6,8,10, 12};//initialzer_list<int>();vector<stirng>原创 2020-10-20 18:52:10 · 184 阅读 · 0 评论 -
关于事件循环
今日方知我是我。参考文章原创 2020-10-12 10:34:02 · 148 阅读 · 1 评论 -
关于thread中mutex相关内容的理解
在C++11中,引入了thread线程库,而为了应对线程的同步,又引入了互斥量mutex,而又因为mutex的各种问题,后续又引申出了使得mutex更安全的机制。下面就以我的个人理解,介绍一下。值得注意的是,下面的内容不涉及到详细的类的使用,而是仅仅对于他们之间的关系做一个梳理。thread库是为了提高应用程序的效率而产生的,但是在thread中,同步却成了一个问题,为了解决这个问题,就引入了一个共享的互斥量mutex。多个线程如果使用的是同一个mutex。mutex有两种状态:lock和unlock原创 2020-10-09 09:42:41 · 702 阅读 · 1 评论 -
关于如何能够“看到”本文件之外的变量或函数的方式
在这几天之前,其实没有想过这方面的东西,虽然一直在用,但是却是没有意识到在使用,比如说#incude某个头文件之类的,今天做一个汇总吧。因为在实际编程中,不可能将所有的东西全部在一个源文件中完成,一般采用的都是多个文件混合编译的情况。在这种情况下,对于某些变量(对象)或者是函数,出于省内存或者是数据共享的目的,如果在某个文件中定义了,实际上并不会再重新写一份一模一样的代码。这个时候一般采用的是将其可见范围扩大,以达到对于其他文件也可用的情况。那么,就来讨论方法了。根据展示内容多寡的标准,可以粗略分为原创 2020-09-27 09:25:38 · 119 阅读 · 0 评论 -
关于extern关键字扩展作用范围的使用方法
extern关键字目前来说主要有两个功能:创建“全局变量”将C++代码按照C的格式进行编译两者的区别主要是其修饰的内容。在修饰函数的时候,比如在函数前加上extern “C",例如extern ”C" void Fun1(int, int);此时就是要求编译器将此函数按照C的方式去编译(因为C++中涉及到函数重载,因此对于同名的函数,编译器在编译的时候会加上参数的类型之类的,如某些编译器可能会将上面的函数编译为Fun1_int_int,这个取决于编译器本身)。在修饰变量或者是对象的时候,则是原创 2020-09-25 10:26:24 · 1019 阅读 · 0 评论 -
关于条件变量condition_variable的使用
condition_variable被称之为“条件变量”,在设置好了需要的条件之后(wait中),只要满足了条件(会发送信号),就会执行,如果不满足就不会执行。示例代码如下:#include <iostream>#include <thread>#include <mutex>#include <condition_variable>#include <deque>using namespace std;deque<int原创 2020-09-18 16:37:10 · 468 阅读 · 0 评论