C++ 学习笔记

不想你离开。 提交于 2020-01-22 12:05:44

前言

学习和工作中经常会遇到一些小问题或者一些技巧性的东西,在此处作一份记录,保持更新。

C++

小技巧

  1. 文件文本读取到std::string:
    std::string filename = "xxxx.txt";
    std::ifstream fin(filename);
    std::string str((std::istreambuf_iterator<char>(fin)), std::istreambuf_iterator<char>());
    

rapidjson

简单使用
  • 从文本中解析json:

    /*test.json*/
    {
        "type": "login",
        "user_id": 4294967202,
        "ver": 262,
        "lang": "zh-CN",
        "state": {},
        "guest": true,
        "uinfo": {
            "id": 4294967202,
            "true_name": "hello"
        },
        "property": {},
        "code": 0
    }
    

    读取文件到string,并解析

    std::ifstream fin(filename);
      if (fin.is_open()) {
        std::string json_str((std::istreambuf_iterator<char>(fin)), std::istreambuf_iterator<char>());
        rapidjson::Document d;
        d.Parse(json_str.c_str());
        if (d.HasParseError()) {
          std::cout << "error" << std::endl;
        }
        std::string type = d["type"].GetString();
        //...
      }
    
  • 构造json对象的两种方式:

      /*
        方式一,较繁琐
      */
      rapidjson::Document d;
      d.SetObject();
      rapidjson::Document::AllocatorType &a = d.GetAllocator(); // 获取分配器
    
      // 基本类型很容易理解
      d.AddMember("Int", 1, a);
      d.AddMember("Double", 2.01, a);
    
      // 字符串类型
      std::string str = "hello world";
      rapidjson::Value str_value(rapidjson::kStringType); // 创建一个字符串类型的Value
      str_value.SetString(str.c_str(), str.size());
      if (!str_value.IsNull()) {
        d.AddMember("String", str_value, a); // 这种方式麻烦,但能保证不出错
        // 直接给字符串字面值也是可以的
        // d.AddMember("String", "hello world", a);
      }
    
      // 嵌套json
      rapidjson::Value obj(rapidjson::kObjectType);
      obj.AddMember("name", "hh", a);
      obj.AddMember("age", 17, a);
      d.AddMember("info", obj, a);
    
      // 数组
      rapidjson::Value arr(rapidjson::kArrayType);
      arr.PushBack(10, a);
      arr.PushBack(20, a);
      d.AddMember("IntArray", arr, a);
    
      // 字符串数组
      // 同上,只是每个元素都需要用rapidjson::Value(kStringType)
    
      /*
        方式二:使用字符串缓冲,十分便捷
      */
      rapidjson::StringBuffer buf;
      rapidjson::Writer<rapidjson::StringBuffer> writer(buf);
    
      writer.StartObject();
    
      // 字符串
      writer.Key("type");
      writer.String("login");
    
      writer.Key("account");
      writer.String("12346789");
    
      // 数组
      writer.StartArray();
      writer.Key("name");
      writer.String("hh");
      writer.Key("age");
      writer.Int(20);
      writer.EndArray();
    
      writer.Key("err_code");
      writer.Int(0);
      writer.EndObject();
    
      // 解析该json字符串
      rapidjson::Document d;
      d.Parse(buf.GetString());
    
  • 将Json对象Stringify

    /*
    	将json对象转为字符串表示,就用缓冲区的方式
    	此处writer有两种选择:
    	1. rapidjson::Writer<T> 转为无缩进和换行的json字符串
    	2. rapidjson::PrettyWriter<T> 转为有缩进和换行的格式化好的字符串表示
    */
    rapidjson::Document d;
    rapidjson::StringBuffer buff;
    rapidjson::Writer<rapidjson::StringBuffer> writer(buff);
    d.Accept(writer); // rapidjson::Value 也可以用这种方式Stringify
    

调试技巧

窗口程序新建控制台进行调试输出

  • 创建控制台:

    /*
    	一个进程只能拥有一个控制台的关联。
    	如果调用该函数的进程已经拥有一个控制台的关联,则AllocConsole函数失败。
    	如果想创建一个新的控制台关联,则进程可以使用FreeConsole函数释放控制台的关联,然后进程可以调用AllocConsole函数来创建一个新的控制台。
    	注意:在使用完控制台程序之后一定要调用FreeConsole函数进行释放,否则造成内存泄漏
    */
    Bool AllocConsole(); // 该函数可以创建一个控制台
    FreeConsole(); // 释放控制台与进程的关联
    
  • 重定向输出:

    HANDLE handle_out = GetStdHandle(STD_OUTPUT_HANDLE); // 获取标准输出Handle,以输出到我们创建的控制台
    char buf[1024] = "hello";
    DWORD len = strlen(buf);
    WriteFile(handle_out, buf, len, &len, 0); // 通过Handle将buffer写入对应的文件或IO设备
    
  • 实现日志类,方便调试:Logger类代码下载 待更新

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!