c++ 学习中记录下来的一些要点,方便以后复习。

1. 变量定义的时候,多使用 auto 关键字。

auto x = (uint8_t)y.x

2. 很多宏定义都可以使用 constexpr 来代替,有很多好处。唯一需要宏定义的地方是预处理。

参考:https://stackoverflow.com/questions/42388077/constexpr-vs-macros

3. #include 可以用 #include 来代替。

4. format string is not a string literal(potentially insecure) 这个警告是在不定参数的函数调用中会出现,起因是编译器没有那么智能。

所以对于类似于 char str[] = "xyz"; log(str) 这样的调用就会报错,有两种解决方法:

  1. 显式的写出来 log("xyz")
  2. 增加第二个参数 log(str, nullptr)。

5. strcat 用于把一个字符串追加到另外一个字符数组里面。

6. snprintf 这个库函数在最后一个位置上面填充 '\0'。

参考: https://www.runoob.com/cprogramming/c-function-snprintf.html

7. json 解析

char strBuf[]="{ \"id\":666, \"name\":\"henryHe\", }";
std::istringstream iss(strBuf);  ////必须得强制类型转换
    Json::Value readValue;
    Json::CharReaderBuilder rbuilder;
    rbuilder["collectComments"] = false;
    std::string errs;
    bool ok = Json::parseFromStream(rbuilder, iss , &readValue, &errs);
    cout <<"ok: "<<ok<<endl;
    cout <<"id: "<<readValue["id"]<<endl;
    std::string name = readValue["name"].asString();
    int id= readValue["id"].asInt();
    cout <<"name: "<<readValue["name"]<<endl;  

参考: https://www.cnblogs.com/music-liang/p/12904554.html https://www.cnblogs.com/esCharacter/p/7657676.html https://blog.csdn.net/centnetHY/article/details/83309796

8. curl,设置 CURLOPT_POSTFIELDS,设置HTTP请求body内容,CURLOPT_POSTFIELDSIZE设置body大小,如果body内容是以\0结尾,可以不指定body大小。

参考: https://cloud.tencent.com/developer/article/1580392

9. 显示时间

    size_t strftime (char* ptr, size_t maxsize, const char* format,
                 const struct tm* timeptr );
    ptr:存储转换结果
    maxsize:复制到ptr的最大字符数,包括结束符'\0'
    format:转换格式,类似printf,可加入其他需要复制过去的字符
    timeptr:时间
    char buf[20];
    tm* local_time = std::localtime(&t);
    strftime(buf,sizeof(buf),"%F %X",local_time);

参考: https://blog.csdn.net/qq_34645629/article/details/84783092 https://stackoverflow.com/questions/6124768/how-to-get-local-time-and-put-it-in-a-string

10. 如果一个类需要放到 vector 中,进行排序,可以在这个类里面进行 运算符重载,然后再需要用的时候,使用 less 或者 greater 之类的函数,注意使用 less, greater 需要

include <functional>

class DetectDetail
{
public:
    std::string mName = "";
    int32_t mScore = 0;
    cv::Rect2i mRectBox = cv::Rect2i(0, 0, 0, 0);
    cv::Rect2i mLabelBox = cv::Rect2i(0, 0, 0, 0);
    std::string mLabel = "";
    cv::Point2i mLabelPos = cv::Point2i(0, 0);
    std::string mPosition = "";

    bool operator<(const DetectDetail &d) const
    {
    if (this->mScore < d.mScore)
        return true;
    else
        return false;
    }

    bool operator>(const DetectDetail &d) const
    {
    if (this->mScore > d.mScore)
        return true;
    else
        return false;
    }
};
#include <functional>

{
    vector<DetectDetail> test;
    DetectDetail tmpD;
    tmpD.mName = "t1";
    tmpD.mScore = 10;
    test.push_back(tmpD);

    tmpD.mName = "t2";
    tmpD.mScore = 20;
    test.push_back(tmpD);
    std::cout << test[0].mName << ", " << test[1].mName << std::endl;

      // 正序
    sort(test.begin(), test.end(), less<DetectDetail>());
    std::cout << test[0].mName << ", " << test[1].mName << std::endl;

      // 倒序
    sort(test.begin(), test.end(), greater<DetectDetail>());
    std::cout << test[0].mName << ", " << test[1].mName << std::endl;
}

参考: https://blog.csdn.net/luofengmacheng/article/details/17259659 https://blog.csdn.net/weixin_41588502/article/details/86620305 http://c.biancheng.net/view/520.html https://blog.csdn.net/qq_42835910/article/details/86774324 https://www.cnblogs.com/lengbingshy/p/3491192.html

11. undefined reference to static class member 在链接的时候,找不到静态成员变量。解决的方法是在 h 头文件中申明静态成员变量,在cpp 文件的源代码中定义静态成员变量,需要注意的是,定义不能再任何函数里面,包括不能再构造函数里面,只能类似于全局变量那种定义的样子。 而且静态成员变量好像不能用 private 来修饰。

参考: https://blog.csdn.net/XSHSZJU216/article/details/44465073

https://blog.csdn.net/fengfengdiandia/article/details/82465987

12. 字符串比较

string 可以用 "==" 或者 string::compare 比较。 字符数组 可以用 strcmp 来比较。

参考: https://blog.csdn.net/zcc1229936385/article/details/79747371 https://blog.csdn.net/ljl1015ljl/article/details/86557512 https://blog.csdn.net/leek5533/article/details/105950109

13. 多线程,c++11 后,有 thread 库可以使用,如果是在线程绑定的是类的成员函数,那么注意需要增加第二个参数,指向这个类的实例。

#include <thread>
#include <iostream>

class Greet
{
    const char *owner = "Greet";
public:
    void SayHello(const char *name) {
        std::cout << "Hello " << name << " from " << this->owner << std::endl;
    }
};
int main() {
    Greet greet;

    std::thread thread(&Greet::SayHello, &greet, "C++11");
    thread.join();

    return 0;
}

上面如果线程是在类里面创建的,那么需要这样用: std::thread thread(&Greet::SayHello, this, "C++11");

参考: https://www.jianshu.com/p/dcce068ee32b

14. 查看 key 是否存在 map 中。

if (mymap.find(key) == mymap.end())
    cout << "没有这个key" << endl;

参考: https://blog.csdn.net/Leo_csdn_/article/details/85066264

15. 获取 vector 的大小

vec.size()

16. c++ 11, 14, 17 特性

参考: https://blog.csdn.net/mc18740458059/article/details/107327243

17. 如何确定 gcc 支持的 c++ 版本。man g++ 搜索 -std= 查找 c++ 版本,或者直接 g++ --version 查找到 g++ 版本,然后去相关网站搜索。

参考: https://blog.csdn.net/tusong86/article/details/105678201

18. cout 打印指针地址,会直接自动打出整个数据。如果想要只打印地址,那么就需要把指针转为空指针,就可以。

cout << "字符串起始地址值: " << static_cast<const void *>(pszStr) << endl;

参考: https://www.cnblogs.com/wxxweb/archive/2011/05/20/2052256.html

19. 读写二进制文件

int main()
{
    CStudent s;
    ofstream outFile("students.dat", ios::out | ios::binary);
    while (cin >> s.szName >> s.age)
        outFile.write((char*)&s, sizeof(s));
    outFile.close();
    return 0;
}
int main()
{
    CStudent s;       
    ifstream inFile("students.dat",ios::in|ios::binary); //二进制读方式打开
    if(!inFile) {
        cout << "error" <<endl;
        return 0;
    }
    while(inFile.read((char *)&s, sizeof(s))) { //一直读到文件结束
        int readedBytes = inFile.gcount(); //看刚才读了多少字节
        cout << s.szName << " " << s.age << endl;   
    }
    inFile.close();
    return 0;
}

参考: http://c.biancheng.net/view/302.html https://blog.csdn.net/lightlater/article/details/6364931

20. 二维指针

float * boxes;
float (*p)[4] = (float(*)[4])boxes;
cout << p[0][0] << p[0][1] << p[0][2] << p[0][3] << endl;

参考: http://c.biancheng.net/view/2022.html

21. 格式化字符串

#include <sstream>
using std::stringstream;
// 准备根据格式造字符串流
stringstream fmt;                       /* 或者使用 ostringstream */
// 造字符串流
fmt << "test string: " << haha << ". test number: " << num;
// 获取最终需要的字符串
string targetString = fmt.str();

参考: https://blog.csdn.net/qq_29695701/article/details/99059536

22. error: default argument given for parameter 。 默认参数只能在申明或者定义中出现一次。一般建议在申明中用默认参数,定义的时候不用。

参考: https://blog.csdn.net/david_xtd/article/details/9704685

23. error: cannot declare member function ‘static ’ to have static linkage。 静态成员函数只能在申明的时候用 static,不能再定义的时候用。

参考: https://blog.csdn.net/guoxiaojie_415/article/details/5364354

24. mutex的 lock 是阻塞的,try_lock 是非阻塞的。

参考: https://blog.csdn.net/zx3517288/article/details/52743011

25. 可以使用 mutex , 也可以使用 lock_guard 或者 unique_lock。

参考: https://www.cnblogs.com/xudong-bupt/p/9194394.html https://www.jianshu.com/p/118aba1b88f1 https://www.cnblogs.com/Asp1rant/p/12420769.html https://www.cnblogs.com/long5683/p/12997011.html

26. segment fault 时,可以选用的工具是: catchsegv,最简单的用法如下:

catchsegv ./test

参考: https://www.cnblogs.com/wahaha02/p/8034112.html https://tinylab-1.gitbook.io/cbook/02-chapter9#toc_7140_15195_7 https://blog.csdn.net/hccloud/article/details/51548274 https://www.cnblogs.com/wpgraceii/p/10622582.html https://blog.csdn.net/u010150046/article/details/77775114 https://www.jianshu.com/p/66e9bc3b4988

27. 读写文本文件

    ifstream inFile(LABEL_FILE, ios::in);
    if (!inFile.is_open())
    {
        cerr << "Error: open labels" << endl;
        return -1;
    }

    string s ="";
    while (inFile >> s) // or while (getline(inFile, s))  
    {
        mLabels.push_back(s);
        cout << "label: " << s << endl;
    }

参考: https://cloud.tencent.com/developer/article/1403612

28. 获取命令行参数,长参数,使用 getopt_long_only(),短参数,使用 getopt


    int opt;
    int optionIndex = 0;
    const char *optString = "anpu";

    static struct option longOptions[] =
    {
        {"all", no_argument, NULL, 'A'},
        {"nfc", no_argument, NULL, 'N'},
        {"pir", no_argument, NULL, 'P'},
        {"usr", no_argument, NULL, 'U'},
        {0, 0, 0, 0}
    };

    while ((opt = getopt_long_only(argc, argv, optString, longOptions,
                                    &optionIndex)) != -1)
    {
        cout << "opt: " << opt << endl;
        cout << "optind: " << optind << endl;
        cout << "option index: " << optionIndex << endl;
        cout << argv[0] << ", " << argv[1] << endl;
        cout << endl;
    }

参考: https://blog.csdn.net/qq_34719188/article/details/83788199 https://blog.csdn.net/zengraoli/article/details/19612627

29. 遍历 map

    for (auto p : digitronMap)
    {
        if (p.first == c)
            return p.second;
    }

参考: https://blog.csdn.net/xiong_min/article/details/87859214

30. mq 错误打印

    gPirEventSend = mq_open("/pir_event", O_WRONLY | O_CREAT | O_NONBLOCK, 0666, &attr);
    if (gPirEventSend == -1)
    {
    cerr << "pir event queue send open error:" << strerror(errno) << endl;
    mq_close(gPirEventSend);
    }

参考: https://blog.csdn.net/mayue_web/article/details/92712163

31. const 内含是文件内使用,和 extern 搭配,容易出问题。 extern const 少用。详见

https://blog.csdn.net/audio_algorithm/article/details/79420067

32. 实现发布订阅模式。

参考: http://www.cs.sjsu.edu/faculty/pearce/modules/patterns/events/pubsubimp.htm https://blog.csdn.net/qq_35865125/article/details/88322729?utm_medium=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.control&dist_request_id=57fa85e0-9ef9-45d3-96dc-1c3dc6422674&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.control https://blog.csdn.net/u011040361/article/details/45308855

33. variable 'std:ofstream' has initializer but incomplete type 错误。

这个保存只要增加头文件 #include <fstream> 即可。 参考: https://blog.csdn.net/whyrun/article/details/7425003

34. 一次性读取文本文件有两种方法

第一种方法:

#include <string>
#include <fstream>
#include <streambuf>

std::ifstream t("file.txt");
std::string str((std::istreambuf_iterator<char>(t)),
                 std::istreambuf_iterator<char>());

注意: std::istreambuf_iterator<char>(t) 这两边必须加括号,否则结果就不对。 第二种方法:

#include <string>
#include <fstream>
#include <sstream>
std::ifstream t("file.txt");
std::stringstream buffer;
buffer << t.rdbuf();
std::string contents(buffer.str());

参考: https://blog.csdn.net/tulip527/article/details/7976471 https://blog.csdn.net/da_kao_la/article/details/85164427 https://blog.csdn.net/vinson0526/article/details/50829627

35. 字符串和字符数组互相转换

char ch [] = "ABCDEFG";
string str(ch);//也可string str = ch;
或者
string str;
str = ch;//在原有基础上添加可以用str += ch;
char ch[10];
ch = s.c_str();

参考: https://www.cnblogs.com/fnlingnzb-learner/p/6369234.html

36. 使用typeid().name()输出变量类型

cout<<typeid(a).name()<<endl;

参考: https://blog.csdn.net/weixin_41770786/article/details/107461573 https://blog.csdn.net/weixin_34074740/article/details/91736705

37. vector 打印

template<typename T>
std::ostream & operator<<(std::ostream & os, std::vector<T> vec)
{
    os<<"{";
    if(vec.size()!=0)
    {
        std::copy(vec.begin(), vec.end()-1, std::ostream_iterator<T>(os,""));
        os<<vec.back();
    }
    os<<"}";
    return os;
}
#include <iterator> // for std::ostream_iterator
#include <algorithm>  // for std::copy

template <typename T>
std::ostream& operator<< (std::ostream& out, const std::vector<T>& v) {
    if (!v.empty()) {
        out << '[';
        std::copy(v.begin(), v.end(), std::ostream_iterator<T>(out, ", "));
        out << "\b\b]";
    }
    return out;
}

参考: https://www.codenong.com/15435313/ https://www.jianshu.com/p/8f25c7e03085

38. transform 只是使用指定的函数对参数进行操作, accumulate 还额外有保存处理数据结果作为下次参数的功能。

参考: https://blog.csdn.net/oMuYeJingFeng1/article/details/26148903 https://blog.csdn.net/fengbingchun/article/details/63252470 https://blog.csdn.net/u011499425/article/details/52756242 https://www.cnblogs.com/mtcnn/p/9423646.html

标签: C++

添加新评论