设计一个KJSon类,支持从xx.json文件解析字符串和生成JSON序列化对象,并写入到xx.json文件中。
关于json格式详情请看教程:JSON详细教程
基本功能:
- 支持解析和生成以下数据类型:
- 字符串
- 整数
- 浮点数
- 布尔值
- 空值(null)
- 对象(嵌套JSON对象)
- 数组(支持嵌套数组)
进阶功能
- 支持动态键名 : 允许使用动态生成的键名进行键值对的添加和访问,支持运行时生成键名的场景。
待完善功能:
- XML序列化格式支持: 扩展序列化功能,使其支持JSON序列化转为XML序列化
- 多线程安全:确保对多线程环境中对JSON对象访问和修改不会产生竞争条件。
KJson.h
-
#pragma once #include <string> #include <vector> #include <map> #include <unordered_map> #include <algorithm> #include<iostream> #define POS 1 //该数字为正 #define UNKNOWNED 0 //该数字为正 #define NEG -1 //该数字为正 #define NOT_INITIAL -1 //该KJson未初始化 #define KJson_NULL 0 //该KJson为空 #define KJson_Bool 1 #define KJson_Int 2 #define KJson_Double 3 #define KJson_String 4 #define KJson_Array 5 #define KJson_Object 6 static const char* IgnoreSpace(const char* in) //用来跳过json里的空格 { while (in && *in && (unsigned char)*in <= 32) in++; return in; } std::string Tab(std::string str, int i) { std::string res; while (i--) { res += str; } return res; } static const unsigned char BOM[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; //实现的功能:支持符号[]和()访问,支持格式化文件输出,支持动态键值对,支持解析报错 //不足:空间使用较大,使用了较多c风格字符串 class KJson { public: KJson(); KJson(const char* json); KJson(const std::string json); KJson& operator[](const std::string key); //使用者需要是json对象,否则返回自己 KJson& operator[](unsigned int i); //使用者需要是json对象,否则返回自己 std::string operator()(const std::string key); //使用者需要是json对象或列表,否则提示错误 std::string operator()(unsigned int i); //使用者需要是json对象或列表,否则提示错误 KJson& operator=(KJson& jj); KJson& operator=(KJson&& jj); KJson& operator=(std::string vstring); //修改键值 KJson& operator=(int vint); //修改键值 KJson& operator=(double vdouble); //修改键值 std::string to_string(); //将内容转化为格式化字符串 void Clear(); //清空内容 ~KJson(); const char* analys(const char* json, const char** error_loc); const char* analys_object(const char* json, const char** error_loc); const char* analys_array(const char* json, const char** error_loc); const char* analys_string(const char* json, const char** error_loc); const char* analys_number(const char* json, const char** error_loc); int get_size(); int get_type(); private: const char* error_loc; //用来存放解析的报错信息 std::string key; //该KJson的键名 int type; //类型 int sign; //如果是整型或者浮点型,标记正负 union Data { std::string* vstring; int* vint; double* vdouble; bool* vbool; void* vnull; // 使用void*来表示null } data; mutable std::unordered_map<unsigned int, KJson*> mapJ_array; //用来存储列表里的内容 mutable std::unordered_map<std::string, KJson*> mapJ_object; //用来存储列表里的内容 void KJson_analys(const char* json, const char** error_loc); }; KJson::KJson() :error_loc(NULL),type(NOT_INITIAL),sign(UNKNOWNED) { data.vstring = NULL; } KJson::KJson(const char* json):error_loc(NULL) { KJson_analys(json, &error_loc); } KJson::KJson(const std::string json):error_loc(NULL) { KJson_analys(json.c_str(), &error_loc); } void KJson::KJson_analys(const char* json, const char** error_loc) { analys(json, error_loc); if (*error_loc!=NULL) { std::cout << "在" <<std::endl<< *error_loc <<std::endl<< "处发生解析错误"<<std::endl; Clear(); } return; } const char* KJson::analys( const char* json, const char** error_loc) { if(!json) { data.vstring = NULL; return 0; } if (!strncmp(json, "false", 5)) { this->type = KJson_Bool; this->data.vbool = new bool(false); return json + 5; } if (!strncmp(json, "true", 4)) { this->type = KJson_Bool; this->data.vbool = new bool(true); return json + 4; } if (!strncmp(json, "null", 4)) { this->type = KJson_NULL; this->data.vnull = NULL; return json + 4; } if (*json == '{') //对象 return analys_object(json, error_loc); if (*json == '[') //列表 return analys_array(json, error_loc); if (*json == '\"') //键值对的键名或者字符串类型键值 return analys_string(json, error_loc); if (*json == '-' || (*json >= '0' && *json <= '9')) return analys_number(json, error_loc); *error_loc = json; return 0; } const char* KJson::analys_object(const char* json, const char** error_loc) { if (*json != '{') { *error_loc = json; return 0; } this->type = KJson_Object; json = IgnoreSpace(json + 1); if (*json == '}')return json + 1;//空的对象 if (*json != '\"') { //std::cout << "wrong format!"; *error_loc = json; return 0; } KJson* child = new KJson; if (!child)return 0; json= IgnoreSpace((*child).analys_string( IgnoreSpace(json), error_loc));//处理对象里第一个键值对的键名 if (!json)return 0; child->key = *(child->data.vstring); delete child->data.vstring; child->data.vstring = NULL; mapJ_object.insert(std::pair<std::string, KJson*>(child->key, child)); if (*json != ':') { *error_loc = json; return 0; } json = IgnoreSpace((*child).analys( IgnoreSpace(json + 1), error_loc)); if (!json)return 0; while (*json == ',') { child = new KJson; json = IgnoreSpace((*child).analys(IgnoreSpace(json + 1), error_loc)); if (!json)return 0; child->key = *(child->data.vstring); delete child->data.vstring; child->data.vstring = NULL; mapJ_object.insert(std::pair<std::string, KJson*>(child->key, child)); if (*json != ':') { *error_loc = json; return 0; } json = IgnoreSpace((*child).analys(IgnoreSpace(json + 1), error_loc)); if (!json)return 0; } if (*json == '}')return json + 1; *error_loc = json; return 0; } const char* KJson::analys_array(const char* json, const char** error_loc) { if (*json != '[') { *error_loc = json; return 0; } this->type = KJson_Array; json = IgnoreSpace(json + 1); if (*json == ']')return json + 1; KJson* child = new KJson; if (!child)return 0; unsigned int i = 0; json = IgnoreSpace((*child).analys(IgnoreSpace(json), error_loc)); mapJ_array.insert(std::pair<unsigned int, KJson*>(i++, child)); if (!json)return 0; while (*json == ',') { child = new KJson; if (!child)return 0; json = IgnoreSpace((*child).analys(IgnoreSpace(json + 1), error_loc)); mapJ_array.insert(std::pair<unsigned int, KJson*>(i++, child)); if (!json)return 0; } if (*json == ']')return json + 1; *error_loc = json; return 0; } const char* KJson::analys_number(const char* json, const char** error_loc) { long long num_int = 0; long double num_double = 0.0; double base = 0.0; double point = 0.1; int a = 0; //记录小数点后面有多少位 int s = 0; //记录指数 int signs = 1; //记录指数正负 this->sign = POS; //初始默认为无符号数 if (*json == '-') { this->sign = NEG; json++; } if (*json == '0')json++; while (*json >= '0' && *json <= '9') { num_int = (num_int * 10) + (*json++ - '0'); } num_double = num_int; //这里可能会丢失数据,需要改进 if (*json == '.') { if (json[1] >= '0' && json[1] <= '9') { json++; base = num_double; do { num_double += point * (*json - '0'); point *= 0.1; base = (base * 10.0) + (*json - '0'); a--; json++; } while (*json >= '0' && *json <= '9'); } else { *error_loc = json; return 0; } } if (*json == 'e' || *json == 'E') { json++; if (*json == '+')json++; else if (*json == '-') { signs = -1; json++; } while (*json >= '0' && *json <= '9') s = (s * 10) + (*json++ - '0'); } if (a == 0 && s == 0) //这是一个整数 { this->data.vint= new int(this->sign * num_int); this->type = KJson_Int; } else { if (s != 0) { num_double = this->sign * base * pow(10.0, (a + s * signs)); } this->data.vdouble = new double( num_double); this->type = KJson_Double; } return json; } const char* KJson::analys_string(const char* json, const char** error_loc) { if (*json != '\"') { *error_loc = json; //std::cout << "not a string"; return 0; } const char* json1 = json + 1;//用于读取双引号里的内容 char* json2; char* json3; int len = 0; unsigned a1, a2; while (*json1 != '\"' && *json1 && ++len)//获得引号内容的真正长度 if (*json1++ == '\\') json1++; json3 = (char*)malloc(len + 1); if (!json3)return 0; json1 = json + 1; json2 = json3; while (*json1 != '\"' && *json1) { if (*json != '\\') *json2++ = *json1++; else { json++; switch (*json) { case 'b': *json2++ = '\b'; break; case 'f': *json2++ = '\f'; break; case 'n': *json2++ = '\n'; break; case 'r': *json2++ = '\r'; break; case 't': *json2++ = '\t'; break; case 'u': //经典的UTF8转换 sscanf_s(json1 + 1, "%4x", &a1); json1 += 4; if ((a1 >= 0xDC00 && a1 <= 0xDFFF) || a1 == 0) break; //非法 if (a1 >= 0xD800 && a1 <= 0xDBFF) { if (json1[1] != '\\' || json1[2] != 'u') break; sscanf_s(json1 + 3, "%4x", &a2); json1 += 6; if (a2 < 0xDC00 || a2 > 0xDFFF) break; a1 = 0x10000 | ((a1 & 0x3FF) << 10) | (a2 & 0x3FF); } len = 4; if (a1 < 0x80) len = 1; else if (a1 < 0x800) len = 2; else if (a1 < 0x10000) len = 3; json2 += len; switch (len) { case 4: *--json2 = ((a1 | 0x80) & 0xBF); a1 >>= 6; case 3: *--json2 = ((a1 | 0x80) & 0xBF); a1 >>= 6; case 2: *--json2 = ((a1 | 0x80) & 0xBF); a1 >>= 6; case 1: *--json2 = (a1 | BOM[len]); } json2 += len; break; default: *json2++ = *json1; break; } json1++; } } *json2 = 0; if (*json1 == '\"') json1++; this->data.vstring = new std::string((std::string)json3); this->type = KJson_String; return json1; //此时json1已经是越过了要处理的一串字符了 } void KJson::Clear() { if (this->type == NOT_INITIAL)return; if(this->type==KJson_String) if(!this->data.vstring) { delete this->data.vstring; return; } if (this->type == KJson_Int) if (!this->data.vint) { delete this->data.vint; return; } if (this->type == KJson_Double) if (!this->data.vdouble) { delete this->data.vdouble; return; } if (this->type == KJson_String) if (!this->data.vstring) { delete this->data.vstring; return; } for (auto iter = mapJ_object.begin(); iter != mapJ_object.end(); iter++) { if (iter->second != NULL) delete iter->second; } this->mapJ_object.clear(); for (auto iter = mapJ_array.begin(); iter != mapJ_array.end(); iter++) { if (iter->second != NULL) delete iter->second; } this->mapJ_array.clear(); } KJson::~KJson() { Clear(); } KJson& KJson::operator[](const std::string key) //获得键名为key的键值对 { if(this->type==KJson_Object){ auto iter = mapJ_object.find(key); if (iter == mapJ_object.end()) //找不到 { KJson* jjnew = new KJson(); jjnew->key = key; this->mapJ_object.insert(std::pair<std::string, KJson*>(key, jjnew)); return (*jjnew); } else { return (*(iter->second)); } } else{ std::cout << "非对象引用,将返回原值" << std::endl; return (*this); } } KJson& KJson::operator[](unsigned int i) { if (this->type == KJson_Array) { auto iter = mapJ_array.find(i); if (iter == mapJ_array.end()) { KJson* jjnew = new KJson(); this->mapJ_array.insert(std::pair<unsigned int, KJson*>(i, jjnew)); return (*jjnew); } else return (*(iter->second)); } else { std::cout << "非列表引用,将返回原值" << std::endl; return (*this); } } std::string KJson::operator()(const std::string key) { auto iter = mapJ_object.find(key); if (iter == mapJ_object.end())return "我不道啊"; KJson* jj = iter->second; if (jj == NULL) return (""); if (jj->type == KJson_String)return *(jj->data.vstring); if (jj->type == KJson_Int) { std::string temp; if (jj->sign == NEG) { if (*(jj->data.vint) <= (long long)INT_MAX && (long long)*(jj->data.vint) >= (long long)INT_MIN) { temp = std::to_string((int)*(jj->data.vint)); } else { temp = std::to_string((long long int)*(jj->data.vint)); } } else { if ((unsigned long long) * (jj->data.vint) <= (long long)UINT_MAX) { temp = std::to_string((unsigned int)*(jj->data.vint)); } else temp = std::to_string((unsigned long long int) * (jj->data.vint)); } return temp; } if (jj->type == KJson_Double) { char temp[200] = { 0 }; if (fabs(*(jj->data.vdouble)) < 0.000001 || fabs(*(jj->data.vdouble)) > 1000000000) { //to_string方法好像没有转换指数形式的重载,所以用snprintf if (jj->sign == NEG)snprintf(temp, sizeof(temp), "-%e", *(jj->data.vdouble)); else snprintf(temp, sizeof(temp), "%e", *(jj->data.vdouble)); } else { if (jj->sign == NEG)snprintf(temp, sizeof(temp), "-%f", *(jj->data.vdouble)); else snprintf(temp, sizeof(temp), "%f", *(jj->data.vdouble)); } return (std::string(temp)); } else if (jj->type == KJson_Bool) { if (*(jj->data.vbool) == false)return "false"; else return "true"; } if (jj->type == KJson_Object) { std::string temp; for (auto iter = jj->mapJ_object.begin(); iter != jj->mapJ_object.end(); iter++) { temp += iter->second->key; temp += " "; } return temp; } if (jj->type == KJson_Array) { std::string temp; for (auto iter = jj->mapJ_array.begin(); iter != jj->mapJ_array.end(); iter++) { temp += iter->second->key; temp += " "; } return temp; } return ""; } std::string KJson::operator()(unsigned int i) { auto iter = mapJ_array.find(i); if (iter == mapJ_array.end())return "我不道啊"; KJson* jj = iter->second; if (jj == NULL)return ""; if (jj->type == KJson_String)return *(jj->data.vstring); if (jj->type == KJson_Int) { std::string temp; if (jj->sign == NEG) { if (*(jj->data.vint) <= (long long)INT_MAX && (long long)*(jj->data.vint) >= (long long)INT_MIN) { temp=std::to_string(*(jj->data.vint)); } else temp=std::to_string((long long)*(jj->data.vint)); } else { if ((unsigned long long)*(jj->data.vint) <= (unsigned long long)UINT_MAX) { temp = std::to_string((unsigned)*(jj->data.vint)); } else temp = std::to_string((unsigned long long)*(jj->data.vint)); } return temp; } if (jj->type == KJson_Double) { char temp[200] = { 0 }; if (fabs(*(jj->data.vdouble))<0.000001||fabs(*(jj->data.vdouble))>100000000) { if (jj->sign == NEG) snprintf(temp, sizeof(temp), "-%e", *(jj->data.vdouble)); else snprintf(temp, sizeof(temp), "%e", *(jj->data.vdouble)); } else { if (jj->sign == NEG)snprintf(temp, sizeof(temp), "-%f", *(jj->data.vdouble)); else snprintf(temp, sizeof(temp), "%f", *(jj->data.vdouble)); } return (std::string(temp)); } if (jj->type == KJson_Bool) { if (*(jj->data.vbool) == false)return "false"; else return "true"; } if (jj->type == KJson_Object) { std::string temp; for (auto iter = jj->mapJ_object.begin(); iter != jj->mapJ_object.end(); iter++) { temp += iter->second->key; temp += " "; } return temp; } if (jj->type == KJson_Array) { std::string temp; for (auto iter = jj->mapJ_array.begin(); iter != jj->mapJ_array.end(); iter++) { temp += iter->second->key; temp += " "; } return temp; } return ""; } std::string KJson::to_string() { if (this == NULL)return ""; if (this->type == KJson_String)return "\""+this->key + "\"" + ":" + "\"" + *(this->data.vstring)+"\"" ; if (this->type == KJson_Int) { int num = *(this->data.vint); std::string temp; if (this->sign == NEG) { if (num <= (long long)INT_MAX && (long long)num >= (long long)INT_MIN) { temp = std::to_string(num); } else temp = std::to_string((long long)num); } else { if ((unsigned long long) num <= (unsigned long long)UINT_MAX) { temp = std::to_string((unsigned)num); } else temp = std::to_string((unsigned long long) num); } return "\"" + this->key + "\"" + ":" + temp ; } if (this->type == KJson_Double) { char temp[200] = { 0 }; double num = *(this->data.vdouble); if (fabs(num) < 0.000001 || fabs(num) > 100000000) { if (this->sign == NEG) snprintf(temp, sizeof(temp), "-%e", num); else snprintf(temp, sizeof(temp), "%e", num); } else { if (this->sign == NEG)snprintf(temp, sizeof(temp), "-%f", num); else snprintf(temp, sizeof(temp), "%f", num); } return "\"" + this->key + "\"" + ":" + std::string(temp); } if (this->type == KJson_Bool) { if (*(this->data.vbool) == false)return "\"" +this->key + "\"" + ":" + "\"" + "false" + "\"" ; else return "\"" + this->key + "\"" + ":" + "\"" + "true" + "\"" ; } if (this->type == KJson_Object) { std::string temp = ""; if (this->key != "")temp = "\"" + this->key + "\"" +":" + "{"; //对象有名字 else temp="{"; if (mapJ_object.begin() == mapJ_object.end())temp += "}"; else { temp += "\n"; for (auto iter = mapJ_object.begin(); iter != mapJ_object.end(); iter++) { temp += " "+(*(iter->second)).to_string() + ",\n"; } temp.erase(temp.size()-2 , 2); temp += "\n }"; } return temp; } if (this->type == KJson_Array) { std::string temp = "\"" + this->key+ "\"" +":" + "["; if (mapJ_array.begin() == mapJ_array.end())temp += "]"; else{ temp += "\n"; for (auto iter = mapJ_array.begin(); iter != mapJ_array.end(); iter++) { temp += " " + (*(iter->second)).to_string() + ",\n"; } temp.erase(temp.size() - 2, 2); temp +="\n ]"; } return temp; } return "\"" + this->key + "\"" + ":" + ""; } KJson& KJson::operator=(KJson& jj) { std::string temp = jj.to_string(); Clear(); if (temp[0] != '{') { const char* json = temp.c_str(); json = IgnoreSpace(this->analys_string(IgnoreSpace(json), &error_loc));//处理对象里第一个键值对的键名 this->key = *(this->data.vstring); delete this->data.vstring; this->data.vstring = NULL; if (*json != ':') { error_loc = json; } analys(IgnoreSpace(json + 1), &error_loc); } else analys(temp.c_str(),&error_loc); //为什么要多加一个temp,是因为jj可能是this的孩子,this先Clear了,孩子没了,就转化不了strign了 return (*this); } KJson& KJson::operator=(KJson&& jj) { std::string temp = jj.to_string(); Clear(); if (temp[0] != '{') { const char* json = temp.c_str(); json = IgnoreSpace(this->analys_string(IgnoreSpace(json), &error_loc));//处理对象里第一个键值对的键名 this->key = *(this->data.vstring); delete this->data.vstring; this->data.vstring = NULL; if (*json != ':') { error_loc = json; } analys(IgnoreSpace(json + 1), &error_loc); } else analys(temp.c_str(), &error_loc); return (*this); } KJson& KJson::operator=(std::string vstring) //对动态键值对进行赋值 { Clear(); this->type = KJson_String; this->data.vstring = new std::string(vstring); return *(this); } KJson& KJson::operator=(int vint) //对动态键值对进行赋值 { Clear(); this->type = KJson_Int; this->data.vint = new int(vint); return *(this); } KJson& KJson::operator=(double vdouble) //对动态键值对进行赋值 { Clear(); this->type = KJson_Double; this->data.vdouble = new double(vdouble); return *(this); } int KJson::get_size() { if (this->type == KJson_Object)return mapJ_object.size(); if (this->type == KJson_Array)return mapJ_array.size(); else return -1; } int KJson::get_type() { return this->type; }
main.cpp
-
#include"KJson.hpp" #include<fstream> #include <sstream> std::string load(std::string filename = "input.txt"); bool output(std::string str, std::string filename = "output.txt"); void chooser(); //交互功能函数 int main() { chooser(); //std::string json= //解析报错功能测试 //"{\"refresh_interval\":60," // "\"dynamic_loading\":[" // "{" // "\"so_path\":\"plugins/User.so\", \"load\":false, \"version\":1," // "\"cmd\":[" // "{\"cmd\":2001, \"class\":\"neb::CmdUserLogin\"}," // "{\"cmd\":2003, \"class\":\"neb::CmdUserLogout\"}" // "]," // "\"module\":[" // "{\"path\":\"im/user/login\", \"class\":\"neb::ModuleLogin\"}," // "{\"path\":\"im/user/logout\", \"class\":\"neb::ModuleLogout\"}" // "]" // "}," // "wrongmessage" //错误信息 // "{" // "\"so_path\":\"plugins/ChatMsg.so\", \"load\":false, \"version\":1," // "\"cmd\":[" // "{\"cmd\":2001, \"class\":\"neb::CmdChat\"}" // "]," // "\"module\":[]" // "}" // "]" // "}"; //KJson jj(json); //std::string json1 = load("res/json_error.txt"); //KJson jj1(json1); /*std::string json="{\"dynamic\":60" //动态键值对测试 "}"; std::string json2 = load(); KJson jj; KJson jj2; jj2= KJson(json2); jj=KJson (json); std::cout << (jj).to_string(); jj.tests = "jj"; KJson jj1; jj1 = jj; jj["data"] = 30; jj["new"] = jj2; std::cout << jj.to_string();*/ return 0; } std::string load(std::string filename) { std::ifstream file(filename); // 以二进制模式打开文件 std::stringstream buffer; if (!file.is_open()) { printf("文件打开异常!\n");//文件打开异常 return ""; } buffer << file.rdbuf(); file.close(); return buffer.str(); } bool output(std::string str, std::string filename) { std::ofstream file(filename); if (!file.is_open()) { printf("文件写入异常!"); return false; } file << str; return true; } void chooser() { int choice; int choice1 = 1; int choice2 = 1; std::string filename; std::string json = load(); std::string key; std::string info; KJson jj(json); KJson jjnew; while (true) { std::cout << "--------------------------------------------------\n" "输入:0结束,1选择json文件(可缺省),2查询,3输出为json文件"<<std::endl; if (!scanf_s("%d", &choice)) { std::cout << "输入错误!"; int c; while ((c = getchar()) != '\n' && c != EOF); } else if (!choice)return; else if (choice == 1) //不选择文件就缺省打开作业给的文件 { std::string temp; std::cout << "请输入文件名"; std::cin >> filename; temp =load(filename); if (temp != "")json = temp; } else if (choice == 2) { jj = KJson(json); jjnew = jj; int i; switch (jjnew.get_type()) { case KJson_Bool:std::cout << "这是一个布尔类型" << std::endl; break; case KJson_Int:std::cout << "这是一个整形类型" << std::endl; break; case KJson_Double:std::cout << "这是一个浮点类型" << std::endl; break; case KJson_NULL:std::cout << "这是一个空值" << std::endl; break; case KJson_String:std::cout << "这是一个字符串类型" << std::endl; break; case KJson_Object: std::cout << "这是一个对象 "<<std::endl ; break; default:std::cout << "到顶"; break; } while (true) { std::cout << "--------------------------------------------------\n" "0结束查询,1进行查询,2回退到初始"; if (!scanf_s("%d", &choice1)) { std::cout << "输入错误!"; int c; while ((c = getchar()) != '\n' && c != EOF); break; } if (!choice1) break; if (choice1 == 1) { std::cout << "请输入要访问的键名或下标" << std::endl; if (jjnew.get_type() != KJson_Array) { std::cin >> key; info = jjnew(key); if (info == "") { std::cout << "查无此项,是否进行添加?\n" "0不添加,1添加" << std::endl; std::cin >> choice2; if (choice2) { std::cout << "输入值:"; std::cin >> info; jjnew[key] = info; } } else { jjnew = jjnew[key]; switch (jjnew.get_type()) { case KJson_Bool:std::cout << "这是一个布尔类型,值为" + info << std::endl; break; case KJson_Int:std::cout << "这是一个整形类型,值为" + info << std::endl; break; case KJson_Double:std::cout << "这是一个浮点类型,值为" + info << std::endl; break; case KJson_NULL:std::cout << "这是一个空值" << std::endl; break; case KJson_String:std::cout << "这是一个字符串类型,值为" + info << std::endl; break; case KJson_Object: std::cout << "这是一个对象,键值对个数: " << jjnew.get_size() << std::endl; std::cout << "键值对的键名如下:" + info << std::endl; break; case KJson_Array: std::cout << "这是一个列表,键值对个数: " << jjnew.get_size()<<std::endl; break; default:std::cout << "该项未初始化"; break; } } } else { std::cin >> i; info = jjnew(i); if (info == "") { std::cout << "下标超出范围,是否进行添加一个新元素进列表?\n" "0不添加,1添加" << std::endl; std::cin >> choice2; if (choice2) { std::cout << "输入值:"; std::cin >> info; jjnew[jjnew.get_size()] = info; } } else { jjnew = jjnew[i]; switch (jjnew.get_type()) { case KJson_Bool:std::cout << "这是一个布尔类型" << std::endl; break; case KJson_Int:std::cout << "这是一个整形类型" << std::endl; break; case KJson_Double:std::cout << "这是一个浮点类型" << std::endl; break; case KJson_NULL:std::cout << "这是一个空值" << std::endl; break; case KJson_String:std::cout << "这是一个字符串类型" << std::endl; break; case KJson_Object: std::cout << "这是一个对象,键值对个数: " << jjnew.get_size()<<std::endl; std::cout << "键值对的键名如下:" + info << std::endl; break; case KJson_Array: std::cout << "这是一个列表,键值对个数: " << jjnew.get_size()<<std::endl; break; default:std::cout << "该项未初始化" << std::endl; break; } } } } else if (choice1 == 2) { jjnew = jj; } else { std::cout << "输入错误!"; break; } } } else if (choice == 3) { if (jj.get_type() != NOT_INITIAL) { std::cout << "输入要目标文件名:" << std::endl; std::cin >> filename; output((jj).to_string(), filename); } else std::cout << "目前还未读取json!" << std::endl; } } }
对于输入文件input.txt,下面给出一个示例:
{
"time": "2018-09-22 12:37:21",
"cityInfo": {
"city": "天津市",
"cityId": "101030100",
"parent": "天津",
"updateTime": "12:32"
},
"date": "20180922",
"message": "Success !",
"status": 200,
"data": {
"shidu": "22%",
"pm25": 15.0,
"pm10": 46.0,
"quality": "优",
"wendu": "24",
"ganmao": "各类人群可自由活动",
"yesterday": {
"date": "21",
"ymd": "2018-09-21",
"week": "星期五",
"sunrise": "05:56",
"high": "高温 25.0℃",
"low": "低温 15.0℃",
"sunset": "18:12",
"aqi": 108.0,
"fx": "西北风",
"fl": "4-5级",
"type": "晴",
"notice": "愿你拥有比阳光明媚的心情"
},
"forecast": [
{
"date": "22",
"ymd": "2018-09-22",
"week": "星期六",
"sunrise": "05:57",
"high": "高温 26.0℃",
"low": "低温 15.0℃",
"sunset": "18:10",
"aqi": 55.0,
"fx": "西北风",
"fl": "4-5级",
"type": "晴",
"notice": "愿你拥有比阳光明媚的心情"
},
{
"date": "23",
"ymd": "2018-09-22",
"week": "星期日",
"sunrise": "05:58",
"high": "高温 23.0℃",
"low": "低温 14.0℃",
"sunset": "18:09",
"aqi": 29.0,
"fx": "西北风",
"fl": "4-5级",
"type": "晴",
"notice": "愿你拥有比阳光明媚的心情"
},
{
"date": "24",
"ymd": "2018-09-22",
"week": "星期一",
"sunrise": "05:59",
"high": "高温 24.0℃",
"low": "低温 15.0℃",
"sunset": "18:07",
"aqi": 25.0,
"fx": "西北风",
"fl": "<3级",
"type": "晴",
"notice": "愿你拥有比阳光明媚的心情"
},
{
"date": "25",
"ymd": "2018-09-22",
"week": "星期二",
"sunrise": "06:00",
"high": "高温 24.0℃",
"low": "低温 16.0℃",
"sunset": "18:05",
"aqi": 56.0,
"fx": "西南风",
"fl": "<3级",
"type": "晴",
"notice": "愿你拥有比阳光明媚的心情"
},
{
"date": "26",
"ymd": "2018-09-22",
"week": "星期三",
"sunrise": "06:01",
"high": "高温 24.0℃",
"low": "低温 17.0℃",
"sunset": "18:04",
"aqi": 86.0,
"fx": "西南风",
"fl": "3-4级",
"type": "阴",
"notice": "不要被阴云遮挡住好心情"
}
]
}
}
交互界面的使用示例如下: