String类
追加
void test_string(void)
{
MyTime myTime;
string filepath = "my_file_";
filepath += myTime.timeDate();
filepath += ".txt";
cout << filepath << endl;
}
测试结果
C++ STL
vector
特点:
连续存储结构;与数组相比,内存空间可动态宽展;支持高效的随机访问、在尾部插入/删除操作,但在其他位置插入/删除效率较低。
内存空间扩展的实现原理:
(1)配置一块新空间
(2)将旧元素逐一搬到新址
(3)释放原来的空间
push_back()
作用:在尾部插入数据
pop_back()
作用:删除容器最后一个元素,该容器size会减1,但capacity不会变化。
erase(pos)
作用:删除容器中pos迭代器指定位置处的元素,并返回下一个位置元素的迭代器。容器size会减1,capacity不变。
swap()
作用:交换容器的内容;引申用法为,释放内存空间。
clear()
作用:删除容器中所有元素,使其变成空容器。容器size减1,capacity不变。
//注:在封装类似printfVector()这样的函数时,尽量使用const关键字,防止数据被异常篡改
void printfVector(const vector<int> &v)
{
for (vector<int>::const_iterator it = v.begin(); it < v.end(); it++)
{
cout << *it << " ";
}
cout << endl;
cout << "size: " << v.size() << " ; ";
cout << "capacity: " << v.capacity() << endl;
return;
}
void test_vector(void)
{
vector<int> v;
for (int i = 0; i < 10; i++)
{
v.push_back(i);
}
printfVector(v);
v.pop_back();
printfVector(v);
vector<int>::iterator pos = v.begin();
v.erase(pos);
printfVector(v);
vector<int> temp_v;
for (int i = 0; i < 5; i++) {
temp_v.push_back(i);
}
cout << "交换前:" << endl;
cout << "v:" ;
printfVector(v);
cout << "tem_v:";
printfVector(temp_v);
temp_v.swap(v);
cout << "交换后:" << endl;
cout << "v:";
printfVector(v);
cout << "temp_v:";
printfVector(temp_v);
//延申用法:压缩v的内存空间
vector<int>(v).swap(v);
printfVector(v);
//延申用法:压缩v的内存空间
v.resize(2);
printfVector(v);
vector<int>(v).swap(v);
printfVector(v);
//延申用法:释放v的内存空间
v.resize(0);
printfVector(v);
vector<int>(v).swap(v);
printfVector(v);
temp_v.clear();
printfVector(temp_v);
return;
}
测试结果:
deque
概念:
双端队列,在功能上合并了vector和list。
特点:
连续存储结构;deque提供了两级数据结构,第一级同vector,代表实际容器,另一级用于维护容器的首地址;和vector相比,支持高效的首/尾端插入/删除操作。
缺点:
相比于vector,占用内存较多。
list
特点:
非连续存储结构;双链表结构,支持向前、向后遍历;支持高效的随机插入/删除操作;
缺点:
随机访问效率低下,需要额外维护指针,开销也比较大;
相比于vector,占用内存多;
vector、deque和list的使用区别
(1)使用vector:需要高效的随机存取,而不在乎插入/删除效率
(2)使用list:需要大量的插入/删除操作,而不关心随机存取
(3)使用deque:需要随机存取,又要支持两端数据的插入/删除
set & multiset
特点
关联式容器;内部采用高效的红黑树;
区别
- set:不可插入重复数据
- multiset:可插入重复数据
erase()
erase(val):删除set容器中存储的元素。
find()
find(val):在set容器中查找值为val的元素。成功-返回该元素的双向迭代器;失败-返回和end()方法一样的迭代器。
自定义排序规则
需要借助仿函数实现。
示例:
struct FileInfo
{
string fileName;
long writeTime;
};
//仿函数(类)
class setCompareByName
{
public:
//重载小括号()
bool operator()(const FileInfo& a, const FileInfo& b) const
{
return (a.fileName < b.fileName);
}
};
class FileProcess
{
public:
FileProcess() {};
~FileProcess() {};
void printfSet(set<FileInfo, setCompareByName>& files)
{
if (!files.empty())
{
for (set<FileInfo>::iterator it = files.begin(); it != files.end(); it++)
{
cout << "fileName: " << it->fileName << "; " << "writeTime: " << it->writeTime << endl;
}
}
else
{
cout << "set is empty" << endl;
}
}
void getFileInfoBySet(string path, set<FileInfo, setCompareByName>& files)
{
DIR* pDir;
struct dirent* ptr;
FileInfo fileInfo;
struct stat buf;
FILE* pFile = NULL;
if (!(pDir = opendir(path.c_str())))
{
cout << "opendir error" << endl;
return;
}
while ((ptr = readdir(pDir)) != 0)
{
if (strcmp(ptr->d_name, ".") == 0 || strcmp(ptr->d_name, "..") == 0)// 跳过.和..文件
{
continue;
}
fileInfo.fileName = ptr->d_name;
string pathName = path + "/" + ptr->d_name;
pFile = fopen(pathName.c_str(), "r");
if (pFile)
{
int fd = fileno(pFile);
fstat(fd, &buf);
fileInfo.writeTime = buf.st_mtime;
fclose(pFile);
}
else
{
cout << "pFile is null" << endl;
fileInfo.writeTime = 0;
}
files.insert(fileInfo);
}
closedir(pDir);
}
};
void custom_file_process_task()
{
FileProcess fileProcess;
string path = "/home/lx/test/video";
while (1)
{
cout << "i am custom_file_process_task" << endl;
set<FileInfo, setCompareByName> filesSet;
fileProcess.getFileInfoBySet(path, filesSet);
cout << "______ [set] files ______" << endl;
fileProcess.printfSet(filesSet);
sleep(5);
}
}
测试结果
实例
获取指定目录下所有文件信息并排序(文件名和修改时间)
要求:获取指定指定目录下所有文件的信息,包括文件名和修改时间,并根据不同因素进行排序。
使用C++ vector实现
.hpp
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <string>
#include <cstring>
#include <vector>
#include <dirent.h>
#include <algorithm>
#include <sys/stat.h>
using namespace std;
struct FileInfo
{
string fileName;
long writeTime;
static bool LessThanByName(FileInfo a, FileInfo b)
{
return (a.fileName < b.fileName);
}
static bool LessThanByWriteTime(FileInfo a, FileInfo b)
{
return (a.writeTime < b.writeTime);
}
};
class FileProcess
{
public:
FileProcess() {};
~FileProcess() {};
void printfVec(vector<FileInfo> &files)
{
if (!files.empty())
{
for (vector<FileInfo>::iterator it = files.begin(); it != files.end(); it++)
{
cout << "fileName: " << it->fileName << "; "<< "writeTime: " << it->writeTime << endl;
}
}
else
{
cout << "vector is empty" << endl;
}
}
void getFileInfo(string path, vector<FileInfo> &files)
{
DIR* pDir;
struct dirent* ptr;
FileInfo fileInfo;
struct stat buf;
FILE* pFile = NULL;
if (!(pDir = opendir(path.c_str())))
{
cout << "opendir error" << endl;
return ;
}
while ((ptr = readdir(pDir)) != 0)
{
if (strcmp(ptr->d_name, ".") == 0 || strcmp(ptr->d_name, "..") == 0)// 跳过.和..文件
{
continue;
}
fileInfo.fileName = ptr->d_name;
string pathName = path + "/" + ptr->d_name;
pFile = fopen(pathName.c_str(), "r");
if (pFile)
{
int fd = fileno(pFile);
fstat(fd, &buf);
fileInfo.writeTime = buf.st_mtime;
fclose(pFile);
}
else
{
cout << "pFile is null" << endl;
fileInfo.writeTime = 0;
}
files.push_back(fileInfo);
}
closedir(pDir);
}
private:
};
.cpp
void custom_file_process_task()
{
FileProcess fileProcess;
string path = "/home/lx/test/video";
while (1)
{
cout << "i am custom_file_process_task" << endl;
vector<FileInfo> filesVec;
fileProcess.getFileInfo(path, filesVec);
fileProcess.printfVec(filesVec);
sort(filesVec.begin(), filesVec.end(), FileInfo::LessThanByName);
cout << "______ after sort LessThanByName ______" << endl;
fileProcess.printfVec(filesVec);
sort(filesVec.begin(), filesVec.end(), FileInfo::LessThanByWriteTime);
cout << "______ after sort LessThanByWriteTime ______" << endl;
fileProcess.printfVec(filesVec);
sleep(5);
}
}
测试结果
使用C++ set实现
.hpp
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <string>
#include <cstring>
#include <dirent.h>
#include <algorithm>
#include <sys/stat.h>
#include <set>
using namespace std;
struct FileInfo
{
string fileName;
long writeTime;
};
//for set
class setCompareByName
{
public:
bool operator()(const FileInfo& a, const FileInfo& b) const
{
return (a.fileName < b.fileName);
}
};
class setCompareByTime
{
public:
bool operator()(const FileInfo& a, const FileInfo& b) const
{
return (a.writeTime < b.writeTime);
}
};
class FileProcess
{
public:
FileProcess() {};
~FileProcess() {};
void printfSet(set<FileInfo, setCompareByName>& files)
{
if (!files.empty())
{
for (set<FileInfo>::iterator it = files.begin(); it != files.end(); it++)
{
cout << "fileName: " << it->fileName << "; " << "writeTime: " << it->writeTime << endl;
}
}
else
{
cout << "set is empty" << endl;
}
}
void getFileInfoBySet(string path, set<FileInfo, setCompareByName>& files)
{
DIR* pDir;
struct dirent* ptr;
FileInfo fileInfo;
struct stat buf;
FILE* pFile = NULL;
if (!(pDir = opendir(path.c_str())))
{
cout << "opendir error" << endl;
return;
}
while ((ptr = readdir(pDir)) != 0)
{
if (strcmp(ptr->d_name, ".") == 0 || strcmp(ptr->d_name, "..") == 0)// 跳过.和..文件
{
continue;
}
fileInfo.fileName = ptr->d_name;
string pathName = path + "/" + ptr->d_name;
pFile = fopen(pathName.c_str(), "r");
if (pFile)
{
int fd = fileno(pFile);
fstat(fd, &buf);
fileInfo.writeTime = buf.st_mtime;
fclose(pFile);
}
else
{
cout << "pFile is null" << endl;
fileInfo.writeTime = 0;
}
files.insert(fileInfo);
}
closedir(pDir);
}
void printfSet(set<FileInfo, setCompareByTime>& files)
{
if (!files.empty())
{
for (set<FileInfo>::iterator it = files.begin(); it != files.end(); it++)
{
cout << "fileName: " << it->fileName << "; " << "writeTime: " << it->writeTime << endl;
}
}
else
{
cout << "set is empty" << endl;
}
}
void getFileInfoBySet(string path, set<FileInfo, setCompareByTime>& files)
{
DIR* pDir;
struct dirent* ptr;
FileInfo fileInfo;
struct stat buf;
FILE* pFile = NULL;
if (!(pDir = opendir(path.c_str())))
{
cout << "opendir error" << endl;
return;
}
while ((ptr = readdir(pDir)) != 0)
{
if (strcmp(ptr->d_name, ".") == 0 || strcmp(ptr->d_name, "..") == 0)// 跳过.和..文件
{
continue;
}
fileInfo.fileName = ptr->d_name;
string pathName = path + "/" + ptr->d_name;
pFile = fopen(pathName.c_str(), "r");
if (pFile)
{
int fd = fileno(pFile);
fstat(fd, &buf);
fileInfo.writeTime = buf.st_mtime;
fclose(pFile);
}
else
{
cout << "pFile is null" << endl;
fileInfo.writeTime = 0;
}
files.insert(fileInfo);
}
closedir(pDir);
}
};
.cpp
void custom_file_process_task()
{
FileProcess fileProcess;
string path = "/home/lx/test/video";
while (1)
{
cout << "i am custom_file_process_task" << endl;
//compare by name
set<FileInfo, setCompareByName> filesSetByName;
fileProcess.getFileInfoBySet(path, filesSetByName);
cout << "______ [set by name] files ______" << endl;
fileProcess.printfSet(filesSetByName);
//compare by time
set<FileInfo, setCompareByTime> filesSetByTime;
fileProcess.getFileInfoBySet(path, filesSetByTime);
cout << "______ [set by time] files ______" << endl;
fileProcess.printfSet(filesSetByTime);
sleep(5);
}
}
测试结果