这篇文章主要介绍了基于c++怎么编写一个JSON解析器的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇基于C++怎么编写一个json解析器文章都会有所收获,下面我们一起来看看吧。代码JsonSerialize.h
这篇文章主要介绍了基于c++怎么编写一个JSON解析器的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇基于C++怎么编写一个json解析器文章都会有所收获,下面我们一起来看看吧。
#pragma once#ifndef _JSON_SERIALIZE_#define _JSON_SERIALIZE_// #include "Util.h"#include <fstream>#include <string>#include <vector>#include <map>// NAME_SPACE_START(Json)enum JsonType { None, Number, String, Array, Bool, Null, Object};class JNull {public: JNull() {} ~JNull() {}};template<typename T>class JBaseObject {public: JBaseObject() {} virtual ~JBaseObject() {} virtual JBaseObject* clone() = 0;};template<typename T>class JHolderObject :public JBaseObject<T> {private:public: T value; JHolderObject(const T& val) :value(val) {} ~JHolderObject() {} JBaseObject<T>* clone() override;};template<typename ValueType>class JObject {private: JBaseObject<ValueType>* _value = nullptr;public: JObject() {} JObject(const ValueType& value); JObject(const JObject& obj) :_value(obj._value->clone()) {} ~JObject(); JObject<ValueType>& operator=(const ValueType& value); ValueType* Cast() { JHolderObject<ValueType>* temp = dynamic_cast<JHolderObject<ValueType>*>(_value); return temp ? &temp->value : NULL; } ValueType& RefCast() { return (static_cast<JHolderObject<ValueType>*>(_value))->value; }};template<typename T>class JsonItemBase {public: JsonItemBase() {} virtual ~JsonItemBase() {} virtual void f() {}};template<typename T>class JsonItem {private: // JObject<T> _value; T _value;public: JsonItem() {} JsonItem(const JsonItem&); JsonItem(const JObject<T>& obj); JsonItem(const T& obj); ~JsonItem() {}; T& GetItemRefValue() { return this->_value; } T* GetItemLpValue() { return &this->_value; }};class JsonKey {public: JsonType _type{ JsonType::None }; std::wstring _key{ L"" }; JsonKey() {} JsonKey(const JsonType& type, const std::wstring& key) :_type(type), _key(key) {} bool operator<(const JsonKey&) const;};class JsonValue {public: void* _value{ nullptr }; size_t _size{ 0 }; JsonValue() {} JsonValue(void* value, const int& size) :_value(value), _size(size) {}};class JsonSerialize { using string = std::string;private: std::vector<std::pair<JsonKey, JsonValue>> content; string _filePath;public: JsonSerialize() {} JsonSerialize(const string filePath); ~JsonSerialize() {}; bool Load(const string filePath = ""); template<typename T> JsonItem<T>* GetValueByKey(string key); std::vector<std::pair<JsonKey, JsonValue>>& GetContent(); void printAll(int tab = 0);private:};// NAME_SPACE_END()#endif //!_JSON_SERIALIZE_
#include "JsonSerialize.h"// #include "Util.h"#include <iOStream>#include <sstream>#include <atomic>#include <exception>#include <fstream>#include <ios>#include <string>#include <utility>#include <vector>#include <stack>// NAME_SPACE_START(Json)template<typename T>JBaseObject<T>* JHolderObject<T>::clone() { return new JHolderObject<T>(this->value);}// template<typename T>// T& JHolderObject<T>::GetValue(){// return value;// }template<typename ValueType>JObject<ValueType>::JObject(const ValueType& value) { _value = new JHolderObject<ValueType>(value);}template<typename ValueType>JObject<ValueType>::~JObject() { if (_value) delete _value;}template<typename ValueType>JObject<ValueType>& JObject<ValueType>::operator=(const ValueType& value) { if (_value) delete _value; _value = new JHolderObject<ValueType>(value); return *this;}// template<typename ValueType>// ValueType* JObject<ValueType>::Cast(){// JHolderObject<ValueType>* temp=dynamic_cast<JHolderObject<ValueType>*>(_value);// return temp?&temp->GetValue():NULL;// }// template<typename ValueType>// ValueType& JObject<ValueType>::RefCast(){// return (dynamic_cast<JHolderObject<ValueType>&>(_value)).GetValue();// }// template<typename T>// JsonItem<T>::JsonItem(const JObject<T>& value)// :JsonItemBase<T>(){// this->_value=value;// }template<typename T>JsonItem<T>::JsonItem(const T& objList){ this->_value = objList;}// //获取值// template<typename T>// T& JsonItem<T>::GetItemRefValue(){// return this->_value.RefCast();// }// template<typename T>// T* JsonItem<T>::GetItemLpValue(){// return this->_value.Cast();// }std::ifstream _file;void OpenFile(const std::string filePath) { _file.open(filePath, std::ios::in); if (!_file.is_open()) return;}void CloseFile() { _file.close();}bool JsonKey::operator<(const JsonKey& j_key) const { return false;}JsonSerialize::JsonSerialize(const std::string filePath) { this->_filePath = filePath;}bool isFirst = true;bool isQuote = false;bool isKey = true;bool isObj = false;bool isObjEnd = true;bool isArrEnd = true;JsonType curType = JsonType::Null;size_t objListDeep = 0;size_t arrDeep = 0;std::wstring key = L"";std::wstring value = L"";std::stack<std::wstring> arrKey;std::stack<JsonType> cer;std::vector<std::pair<bool,JsonItem<std::vector<JsonValue>>*>> arrValueList; //false直接放到对象中 true 放到objList中std::vector<std::pair<bool,JsonItem<JsonSerialize>*>> objList; //false直接放到对象中 true 放到arrValueList中void freeAll() { for (std::pair<bool, JsonItem<std::vector<JsonValue>>*> item : arrValueList) if (item.second) delete item.second; for (std::pair<bool, JsonItem<JsonSerialize>*> item : objList) if (item.second) delete item.second;}std::string stows(std::wstring& ws){ std::string curLocale = setlocale(LC_ALL, NULL); // curLocale = "C"; setlocale(LC_ALL, "chs"); const wchar_t* _Source = ws.c_str(); size_t _Dsize = 2 * ws.size() + 1; char* _Dest = new char[_Dsize]; memset(_Dest, 0, _Dsize); wcstombs(_Dest, _Source, _Dsize); std::string result = _Dest; delete[]_Dest; setlocale(LC_ALL, curLocale.c_str()); return result;}bool isBool(const std::wstring& str) { return str == L"true";}bool isNumber(const std::wstring& str) { std::wstring wstr = str; std::stringstream ss(stows(wstr)); double d; char c; if (!(ss >> d)) return false; if (ss >> c) return false; return true;}bool Analysis(const char* buffer, std::vector<std::pair<JsonKey, JsonValue>>& content, const size_t length) { size_t charLength = strlen(buffer) < length ? strlen(buffer) : length; for (size_t i = 0; i < charLength; i++) { char ch = buffer[i]; std::cout << ch; if (ch == '{' && !isQuote) { objListDeep++; curType = JsonType::Object; if (objListDeep >= 2) { bool flag = (cer.empty() || cer.top() == JsonType::Object) ? false : true; objList.push_back(std::pair<bool, JsonItem<JsonSerialize>*>(flag, new JsonItem<JsonSerialize>())); isObj = true; isObjEnd = false; if (!isArrEnd) cer.push(JsonType::Array); cer.push(JsonType::Object); if (isKey) arrKey.push(L""); } } else if (ch == '}' && !isQuote) { if (objListDeep == 1 && isFirst == true) isFirst = false; else if (objListDeep == 1 && isFirst == false) return false; objListDeep--; isObjEnd = true; if (objListDeep != 0) Goto addArray; } else if (ch == '[' && !isQuote) { bool flag = (cer.empty() || cer.top() == JsonType::Object) ? false : true; curType = JsonType::Array; arrDeep++; arrValueList.push_back(std::pair<bool, JsonItem<std::vector<JsonValue>>*>(flag,new JsonItem<std::vector<JsonValue>>())); isArrEnd = false; if (!isObjEnd) cer.push(JsonType::Object); cer.push(JsonType::Array); } else if (ch == ']' && !isQuote) { arrDeep--; if (arrDeep == 0) isArrEnd = true; goto addArray; } else if (ch == ' ' && !isQuote) continue; else if (ch == '"' && !isQuote) { isQuote = true; if (isKey) key += L"\""; else value += L"\""; } else if (ch == '"' && isQuote) { isQuote = false; if (isKey) key += L"\""; else value += L"\""; } else if (ch == ':' && !isQuote) isKey = false; else if ((ch == ',' || ch == '\n') && !isQuote) { if ((key == L"" && value == L"" && objList.size() == 0 && arrValueList.size() == 0) || (key == L"" && value == L"" && !isArrEnd)) continue;addArray: std::wstring inpuTKEy = key == L"" ? L"" : key.replace(0, 1, L""); inputKey = inputKey == L"" ? L"" : inputKey.replace(inputKey.find_last_of(L"\""), 1, L""); JsonKey j_key; JsonValue j_value; JsonType insertType = JsonType::Null; j_key._key = inputKey; if (value == L"true" || value == L"false") { //Bool JsonItem<bool> *objList=new JsonItem<bool>(isBool(value)); size_t size = sizeof(objList); j_value._value = objList; j_value._size = 1; j_key._type = JsonType::Bool; } else if (value.find(L"\"") == 0 && value.find_last_of(L"\"") == value.size() - 1) { //String size_t n = value.size(); std::wstring* temp = new std::wstring(value.begin(), value.end()); JsonItem<std::wstring*> *objList=new JsonItem<std::wstring*>(temp); j_value._value = objList; j_value._size = n; j_key._type = JsonType::String; } else if (isNumber(value)) { //Number double result = 0; std::stringstream ss(stows(value)); ss >> result; JsonItem<double> *objList=new JsonItem<double>(result); size_t size = sizeof(objList); j_value._value = objList; //memcpy_s(j_value._value, size, &objList, size); j_value._size = 1; j_key._type = JsonType::Number; } else if (arrValueList.size() != 0 && objList.size() != 0) {//Array Add or Object Add if (!isObjEnd) { arrKey.push(inputKey); key = L""; isKey = true; continue; } cer.pop(); void* _val = curType == JsonType::Object ? (void*)objList.back().second : (void*)arrValueList.back().second; size_t _si = curType == JsonType::Object ? objList.back().second->GetItemRefValue().GetContent().size() : arrValueList.back().second->GetItemLpValue()->size(); j_key._key = arrKey.top(); j_value._value = _val; j_value._size = _si; j_key._type = JsonType::Object; if (curType == JsonType::Object) objList.pop_back(); else arrValueList.pop_back(); //接下来确认是放到obj 还是 arrvalue 通过cer栈顶元素判断 JsonType upType = cer.top(); arrKey.pop(); if (upType == JsonType::Object) objList.back().second->GetItemLpValue()->GetContent().push_back(std::pair<JsonKey, JsonValue>(j_key, j_value)); else arrValueList.back().second->GetItemLpValue()->push_back(j_value); continue; } else if (objList.size() != 0) {//Object if (!isObjEnd && isKey) { arrKey.push(inputKey); key = L""; continue; } cer.pop(); j_key._key = arrKey.top(); arrKey.pop(); j_value._value = objList.back().second; j_value._size = objList.back().second->GetItemRefValue().GetContent().size(); j_key._type = JsonType::Object; objList.pop_back(); if (objList.size() != 0) { objList.back().second->GetItemLpValue()->GetContent().push_back(std::pair<JsonKey, JsonValue>(j_key, j_value)); continue; } } else if (arrValueList.size() != 0 && objList.size() == 0) {//Array if (!isArrEnd) { arrKey.push(inputKey); key = L""; isKey = true; continue; } cer.pop(); j_key._key = arrKey.empty()?inputKey:arrKey.top(); if (!arrKey.empty()) arrKey.pop(); j_value._value = arrValueList.back().second; j_value._size = arrValueList.back().second->GetItemLpValue()->size(); j_key._type = JsonType::Array; arrValueList.pop_back(); if (arrValueList.size() != 0) { arrValueList.back().second->GetItemLpValue()->push_back(j_value); continue; } } else if (value == L"") { //Null JsonItem<JNull>* objList = new JsonItem<JNull>(); size_t size = sizeof(objList); j_value._value = objList; j_value._size = 0; j_key._type = JsonType::Null; } std::pair<JsonKey, JsonValue> pair(j_key, j_value); if (!isObjEnd) { objList.back().second->GetItemRefValue().GetContent().push_back(pair); } else content.push_back(pair); key = L""; value = L""; isKey = true; if (objListDeep == 1 && isObj) isObj = false; } else { if (isKey && isQuote) key += std::wstring(1, ch); else if (isKey && !isQuote) return false; else if (!isKey) value += std::wstring(1, ch); } if (objListDeep < 0 || arrDeep < 0) return false; } return true;}bool JsonSerialize::Load(const string filePath) { try { if (filePath != "") { this->_filePath = filePath; } OpenFile(this->_filePath); while (!_file.eof()) { char buffer[0x4000] = ""; size_t length = sizeof(buffer) / sizeof(char); _file.read(buffer, length); if (!Analysis(buffer, content, length)) { CloseFile(); return false; } } CloseFile(); freeAll(); return objListDeep == 0 && arrDeep == 0; } catch (std::exception ex) { throw ex; }}std::vector<std::pair<JsonKey, JsonValue>>& JsonSerialize::GetContent() { return this->content;}template<typename T>JsonItem<T>* JsonSerialize::GetValueByKey(string key){ JsonItem<T>* temp_value = nullptr; for (auto item : this->content) { if (item.first._key == key) { temp_value = (JsonItem<T>*)(item.second._value); break; } } return temp_value;}void coutTab(int count) { while (count--) { std::cout << '\t'; }}void JsonSerialize::printAll(int tab) { auto res = this->content; coutTab(tab); std::cout << "{" << std::endl; for (auto it = res.begin(); it != res.end(); it++) { JsonKey temp_key = it->first; if (temp_key._type == JsonType::Number) { JsonItem<double>* temp_value = (JsonItem<double>*)(it->second._value); coutTab(tab + 1); std::wcout << temp_key._key << " : " << temp_value->GetItemRefValue() << std::endl; } else if (temp_key._type == JsonType::String) { JsonItem<std::wstring*>* temp_value = (JsonItem<std::wstring*>*)(it->second._value); coutTab(tab + 1); std::wcout << temp_key._key << " : " << *temp_value->GetItemRefValue() << "" << std::endl; } else if (temp_key._type == JsonType::Null) { JsonItem<JNull>* temp_value = (JsonItem<JNull>*)(it->second._value); coutTab(tab + 1); std::wcout << temp_key._key << " : " << "NULL" << std::endl; } else if (temp_key._type == JsonType::Bool) { JsonItem<bool>* temp_value = (JsonItem<bool>*)(it->second._value); coutTab(tab + 1); std::wcout << temp_key._key << " : " << (temp_value->GetItemRefValue() ? "true" : "false") << std::endl; } else if (temp_key._type == JsonType::Object) { JsonItem<JsonSerialize>* temp_value = (JsonItem<JsonSerialize>*)(it->second._value); temp_value->GetItemRefValue().printAll(tab + 1); } else if (temp_key._type == JsonType::Array) { JsonItem<std::vector<JsonValue>>* temp_value = (JsonItem<std::vector<JsonValue>>*)(it->second._value); coutTab(tab + 1); std::wcout << temp_key._key << ":[" << std::endl; for (auto item : temp_value->GetItemRefValue()) { JsonItem<JsonSerialize>* tt_value = (JsonItem<JsonSerialize>*)(item._value); tt_value->GetItemLpValue()->printAll(tab + 2); } coutTab(tab + 1); std::cout << "]" << std::endl; } } coutTab(tab); std::cout << "}" << std::endl;}// NAME_SPACE_END()
int main() { JsonSerialize json("F:\\C++\\mySource\\example\\test.json"); json.Load(); json.printAll(); return 0;}
关于“基于C++怎么编写一个Json解析器”这篇文章的内容就介绍到这里,感谢各位的阅读!相信大家对“基于C++怎么编写一个Json解析器”知识都有一定的了解,大家如果还想学习更多知识,欢迎关注编程网其他教程频道。
--结束END--
本文标题: 基于C++怎么编写一个Json解析器
本文链接: https://www.lsjlt.com/news/351136.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
下载Word文档到电脑,方便收藏和打印~
2024-03-01
2024-03-01
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0