json解析器的代码实现
设计一个KJSon类,支持从xx.json文件解析字符串和生成JSON序列化对象,并写入到xx.json文件中。
基本功能:
- 支持解析和生成以下数据类型:
- 字符串
- 整数
- 浮点数
- 布尔值
- 空值(null)
- 对象(嵌套JSON对象)
- 数组(支持嵌套数组)
进阶功能
- 支持动态键名 : 允许使用动态生成的键名进行键值对的添加和访问,支持运行时生成键名的场景。
待完善功能:
- XML序列化格式支持: 扩展序列化功能,使其支持JSON序列化转为XML序列化
- 多线程安全:确保对多线程环境中对JSON对象访问和修改不会产生竞争条件。
KJson.hpp
点击查看代码
#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回退到初始"<<std::endl;
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 << "查无此项,是否进行添加?" << std::endl<<
"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
对于输入文件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": "不要被阴云遮挡住好心情"
}
]
}
}
交互界面的使用示例如下:


浙公网安备 33010602011771号