常用的C++小代码段

mac2024-03-06  33

目录:

win10上在程序中调用.exe文件,并获取返回值任意给出一个路径(非根目录),找到上一层目录使用C++标准库中的thread类编写多线程程序在结构体中定义函数C++复制文件C++如何判断某一个目录是否存在?创建文件夹?删除文件夹?C++调用OpenCV对视频文件进行解帧以及将图片压缩为视频文件linux下的程序计时操作

1、win10上在c++中调用.exe文件,并获取返回值

这里只比较其中的两种方式:WinExec和system。它们的区别是: WinExec()有两个参数,第一个参数是要执行的cmd,第二个参数可以设置窗口如何显示。但是要注意的是WinExec()是不同步的进程调用,一经调用立刻就会返回一个值(这个值用来表示是否调用成功),如果调用成功则返回值大于31,调用失败则返回值小于31。system()只有一个参数,就是要执行的cmd命令。system()是同步调用进程的方式,调用的进程不结束,就不会返回。

可以用下面的程序测试一下,运行结果有明显的不同:

#include <iostream> #include <thread> int main() { for(int i=0; i<10; i++) { std::this_thread::sleep_for(std::chrono::milliseconds(1000)); std::cout << "i = " << i << std::endl; } return 0; }

下面的程序调用上面的程序经过编译-连接后生成的.exe文件:

#include <iostream> #include <thread> #include <Windows.h> int main() { std::string command = "E:\\code\\cpp_learn\\while_10\\x64\\while_10.exe"; //int result = WinExec(command.data(), SW_SHOW); int result = system(command.data()); std::cout << "result = " << result << std::endl; return 0; }

下面依次是使用WinExec()、system()的运行结果:可以很清楚的看到两者的区别。

2、查找任意一个路径(非根目录)的上一层目录---进行字符串反向查找"\\"并截取字符串即可

std::string find_last_dir(std::string path) { std::string::size_type pos; pos = path.rfind("\\"); return path.substr(0, pos); }

3、使用c++标准库中的thread类来编写多线程程序

使用thread来编写多线程程序时非常方便的。

首先要导入头文件#include 并且声明使用std名字空间using namespace std;。然后要注意的是线程需要有一个“开始”的地方,就是线程入口的函数,也可以直接称为线程函数。当线程函数返回时,线程也就随之终止了。

启动线程的两个方法:join()或者detach()

如果选用join()方法时,主线程(可以认为main函数也是一个线程)会阻塞住,直接该子线程退出为止,然后主线程继续顺序执行。 如果选择detach()方式:执行的线程从线程对象中被独立独立运行,主线程丧失对子线程的控制权。(可能main已经执行结束了,但是子线程还没有结束)这就引出了两个需要注意的问题: 主线程结束之后,子线程可能还在执行(因而可以作为守护线程) 主线程结束伴随着资源销毁,所以需要保证子线程没有引用这些资源。 下面是一个很简单的多线程线程的例子:

#include <iostream> #include <thread> #include <string> void thread_func(std::string tName) { for (int i = 0; i < 10; i++) { std::cout << "线程" << tName << "执行了 " << i << " 次" << std::endl; std::this_thread::sleep_for(std::chrono::milliseconds(100)); } } int main() { std::thread t1(thread_func, "A"); std::thread t2(thread_func, "B"); t1.join(); t2.join(); std::cout << "main结束" << std::endl; }

下面是运行结果: 从运行结果中可以看到:两个线程都结束了之后,main函数继续向下执行,输出“main结束”。但是现在出现问题了:

std::cout << "线程" << tName << "执行了 " << i << " 次" << std::endl;

比如说线程A执行这条语句,但是还没有执行完,就被B“抢”过去执行了。

要解决这个问题,可以对其进行加锁—信号量机制。 c++11提供了std::mutex类,在头文件mutex中声明,因此要首#include<mutex>。

代码修改如下:

#include <iostream> #include <thread> #include <string> #include <mutex> std::mutex tLock; void thread_func(std::string tName) { for (int i = 0; i < 10; i++) { tLock.lock(); std::cout << "线程" << tName << "执行了 " << i << " 次" << std::endl; tLock.unlock(); std::this_thread::sleep_for(std::chrono::milliseconds(100)); } } int main() { std::thread t1(thread_func, "A"); std::thread t2(thread_func, "B"); t1.join(); t2.join(); std::cout << "main结束" << std::endl; }

运行结果如下:

4、在结构体中定义函数

c++中是允许在结构体中定义函数的,它的用法和类的用法很像,不过与类有一个区别在于**struct中定义的函数和变量都是默认为public类型的,但是class中默认的是private类型**。

下面同样给出一个简单例子:

#include <iostream> #include <string> using namespace std; typedef struct Person { string name; string sex; int age; Person(string _name, string _sex, int _age) { name = _name; sex = _sex; age = _age; } string to_string() { string str; str = "name: " + name + "\nsex: " + sex + "\nage: " + std::to_string(age); return str; } }; int main() { Person a("Robert", "man", 25); cout << a.to_string() << endl; return 0; }

5、C++复制文件

这里直接使用简单粗暴的方式,先用ifstream、ofstream打开文件(以w模式打开文件,如果文件不存在的话会自动创建文件),然后一边读一边写实现复制操作。

函数定义如下:

inline void copy_file(string old_file_name, string new_file_name) { ifstream in(old_file_name, std::ios::in); ofstream out(new_file_name, std::ios::out); if (!(in.is_open() && out.is_open())) { cout << "Error!" << endl; } string line; while (getline(in, line)) { out << line << endl; } in.close(); out.close(); }

上面的小代码段都很小,平时可以用来做一些简单、重复的处理,类似于脚本。需要的时候拿过来用就好了。

公众号中还有很多有趣的东西哦,是一个SLAM、ML/DL、论文学习的一个分享平台。只推干货,宁缺毋滥。

6、C++如何判断某一个目录是否存在?创建文件夹?删除文件夹?

在C++标准库中没有直接对目录操作的函数(反正我没找到),因此在需要操作文件夹的时候使用系统平台函数比较方便。同时系统函数在windows平台和Linux平台上有一定的区别。

判断文件和文件夹是否存在以及是否具有访问权限:

windows: 函数: int access(const char* _Filename, int AccessMode) 头文件: io.h Linux: int access(const char* _Filename, int AccessMode)] 头文件:unistd.h 功能:确定文件和文件夹是否存在或者是否具有访问权限,有指定访问权限则返回0,否则返回-1。 AccessMode参数: 00表示只判断是否存在 02表示文件是否可执行 04表示文件是否可写 06表示文件是否可读

创建文件夹:

windows: 函数:int mkdir(const char* _Path) 头文件:direct.h Linux: 函数:int mkdir(const char* pathname, mode_t mode) 头文件:sys/types.h, sys/stat.h 功能:创建文件夹,返回0为创建成功,否则返回-1

删除文件夹:

windows: 函数: int rmdir(const char* _Path) 头文件:direct.h linux: 函数:int rmdir(const char* _Path) 头文件:sys/types.h, sys/stat.h 功能: 删除文件夹,成功返回0,否则-1

7、C++调用OpenCV对视频文件进行解帧以及将图片压缩为视频文件

#include <opencv2\opencv.hpp> #include <iostream> #include <vector> class Video2Image { private: const std::string conWindowName; std::string video_full_name; std::string image_dir; public: Video2Image(std::string video_full_name_, std::string image_dir_, std::string current_image_); void toImage(); void toVideo(); }; Video2Image::Video2Image(std::string video_full_name_, std::string image_dir_, std::string current_image_) :conWindowName(current_image_) { video_full_name = video_full_name_; image_dir = image_dir_; } void Video2Image::toImage() { cv::VideoCapture cap; cap.open(video_full_name); if (cap.isOpened()) { cv::Mat frame; char img_full_name[256]; cv::namedWindow(conWindowName, CV_WINDOW_NORMAL); for (int i = 0; cap.read(frame); ++i) { cv::imshow(conWindowName, frame); cv::waitKey(1); sprintf(img_full_name, "%s\\%04d.jpg", image_dir.c_str(), i); cv::imwrite(img_full_name, frame); } cv::destroyWindow(conWindowName); } else { std::cout << "Open " << video_full_name << " failed..." << std::endl; } } void Video2Image::toVideo() { std::vector<cv::String> img_names; cv::glob(image_dir, img_names); int counts = image_dir.size(); //打开视频文件 cv::VideoWriter vw; std::cout << video_full_name << std::endl; vw.open( video_full_name, CV_FOURCC('M', 'J', 'P', 'G'), 25, cv::imread(img_names[0]).size(), true ); char img_full_name[256]; for (int i = 0; i < img_names.size(); i++) { sprintf(img_full_name, "%s\\%04d.jpg", i); vw.write(cv::imread(img_full_name)); cv::waitKey(1); } rw.release(); }

8、linux下的计时操作

可用于测量程序的执行时间。也是经常要用到的。通过gettimeofday()实现,可精确到微秒级别。 需要使用到结构struct timeval,定义如下: struct timeval { time_t tv_sec; //秒 long tv_usec; //微秒 };

gettimeofday()返回自1970-01-01 00:00:00到现在经历的秒数。

#include <sys/time.h> #include <iostream> using namespace std; int main() { struct timeval start, end; gettimeofday(&start, NULL); for(int i=0; i<100; ++i) { cout << "i = " << i << endl; } gettimeofday(&end, NULL); //毫秒级别 double cost_time = (end.tv_sec - start.tv_sec) * 1000.0 + (end.tv_usec - start.tv_usec) / 1000.0; cout << "for循环耗时:" << cost_time << "毫秒." << endl; //微秒 double cost_time_1 = (end.tv_sec - start.tv_sec) * 1000000.0 + (end.tv_usec - start.tv_usec); cout << "for循环耗时:" << cost_time_1 << "微秒." << endl; return 0; }

运行结果:

最新回复(0)