Some C++ Snippets

1. Sort a vector and Get the Index

vector values存储一个list, 得到list中从大到小的index序列

struct IdxCompare {
    const std::vector<float>& target;
    IdxCompare(const std::vector<float>& target): target(target) {}  // 导入要排序的list
    bool operator()(int a, int b) const { return target[a] > target[b]; }  // 重载这个
};
vector<size_t> indices(values.size());  // store the sorted index
for(int i=0; i<values.size(); i++)
    indices[i] = i;
sort(indices.begin(), indices.end(), IdxCompare(values));  // 传进去

如果是C++11(>=g++4.8),可以调用Lamdba表达式

vector<size_t> indices(values.size());
std::iota(begin(indices), end(indices), static_cast<size_t>(0));
std::sort(
	begin(indices), end(indices),
	[&](size_t a, size_t b) { return values[a] > values[b]; }  // 非常简洁
);

2. stringstream进行数据类型转换

比sprintf等转换更简单,安全,方便 reference

#include <sstream>
template<class out_type,class in_value>
out_type convert(const in_value& t)
{
    std::stringstream stream;
    out_type result;        //这里存储转换结果
    
    stream << t;            //向流中传值
    stream >> result;       //向result中写入值
    return result;
}
// 使用
double outv;
std::string inv = "2.34";
outv = convert<double>(inv);  // Note: 模版参数可以省略第二个string,因为可以推断出来
std::string outv2 = convert<std::string>(outv);  // 2.34
// stringstream有临时缓冲区,可以一直往里写东西,最后统一写入文件,这样效率高
ofstream ofile("output.txt");
ostringstream oss;
oss << "blablabla" << endl;  // 多次写入
ofile << oss.str();  // 一次性写入文件
// 多次使用时,需要清空之前的内容时
oss.clear();  // 清空标志位
oss.str("");  // 清空内容,设置为空

另,高级用法参考C++ 之定制输入输出流

3. 文件夹和文件操作

std::string findDirRecursively(const std::string &dirToFind, std::string curDir) {
    struct dirent *ptr;
    DIR *dir;
    while (1) {                                         // find the dir upwords
        if ((dir = opendir(curDir.c_str())) == NULL) {  // open the dir
            std::cerr << "Error open dir: " << curDir << std::endl;
            break;
        }
        while ((ptr = readdir(dir)) != NULL) {
            if ((ptr->d_type == 4) && (std::string(ptr->d_name) == dirToFind)) {
                // std::cout << "Find " << dirToFind << " in " << curDir << std::endl;
                return curDir + dirToFind + std::string("/");
            }
        }
        closedir(dir);
        curDir = std::string("../") + curDir;
    }
    return std::string();
}

4. 正则表达式

// regex_match  必须全字符串匹配
if(std::regex_match("/a/b/c.x", sm, std::regex("(.*)\/(.*)(\.x$|\.y$)"))) {
    for(auto i: sm)  std::cout << i << std::endl;  // /a/b/c.x ; /a/b ; c ; .x
}
// regex_replace
std::regex_replace("a.json", std::regex("(.*)\.json"), "$1.bin");  // a.bin
// 匹配数字
std::regex integer("(\\+|-)?[0-9]+");
std::regex integer("(\\+|-)?\\d+");
std::regex integer(R"((\+|-)?\d+)");  // raw string更简洁,少\
std::regex integer("(\\+|-)?[[:d:]]+");  // 更通用,包括诡异国家的数字字符
Loading Disqus comments...
Table of Contents