前言
学习和工作中经常会遇到一些小问题或者一些技巧性的东西,在此处作一份记录,保持更新。
C++
小技巧
- 文件文本读取到
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设备
-
实现日志类,方便调试:编写VC++日志类(Logger) ---- 方便调试