欧美free性护士vide0shd,老熟女,一区二区三区,久久久久夜夜夜精品国产,久久久久久综合网天天,欧美成人护士h版

首頁綜合 正文
目錄

柚子快報邀請碼778899分享:C++ JSON解析

柚子快報邀請碼778899分享:C++ JSON解析

http://yzkb.51969.com/

JSON解析

JSONCPPC++實現(xiàn)JSON解析器

JSONCPP

JSONCPP源碼鏈接:https://github.com/open-source-parsers/jsoncpp

JSOCPP源碼下載以后,首先復(fù)制一份include文件夾下的json文件夾,頭文件留著后續(xù)備用。 使用Cmake生成項目。在IDE中編譯jsoncpp_lib,可以在項目的lib/Debug文件夾下找到j(luò)soncpp.lib,在bin/Debug/文件夾下找到j(luò)soncpp.dll。將頭文件和動態(tài)鏈接庫文件,放入項目中即可使用。 jsoncpp庫中的類被定義到了一個Json命名空間中,使用時最好先聲明這個命名空間。

使用jsoncpp庫解析json格式的數(shù)據(jù),三個類:

Value 類:將json支持的數(shù)據(jù)類型進行了包裝,最終得到一個Value類型。FastWriter類:將Value對象中的數(shù)據(jù)序列化為字符串。Reader類:反序列化,將json字符串解析成Value類型。

C++實現(xiàn)JSON解析器

#pragma once

#include

#include

#include

#include

#include

namespace Cliu {

namespace json {

class JsonElement;

using JsonObject = std::map;

using JsonArray = std::vector;

class JsonElement {

public:

enum class Type {

JSON_OBJECT,

JSON_ARRAY,

JSON_STRING,

JSON_NUMBER,

JSON_BOOL,

JSON_NULL

};

union Value {

JsonObject* value_object;

JsonArray* value_array;

std::string* value_string;

float value_number;

bool value_bool;

};

JsonElement() : JsonElement(Type::JSON_NULL) {}

JsonElement(const Type& type) : type_(type) {

switch (type) {

case Type::JSON_OBJECT:

value_.value_object = new std::map();

break;

case Type::JSON_ARRAY:

value_.value_array = new std::vector();

break;

case Type::JSON_STRING:

value_.value_string = new std::string("");

break;

case Type::JSON_NUMBER:

value_.value_number = 0;

break;

case Type::JSON_BOOL:

value_.value_bool = false;

break;

case Type::JSON_NULL:

break;

default:

break;

}

};

JsonElement(JsonObject* object) : type_(Type::JSON_OBJECT) { value(object); }

JsonElement(JsonArray* array) : type_(Type::JSON_ARRAY) { value(array); }

JsonElement(std::string* str) : type_(Type::JSON_STRING) { value(str); }

JsonElement(float number) : type_(Type::JSON_NUMBER) { value(number); }

JsonElement(bool val) : type_(Type::JSON_BOOL) { value(val); }

~JsonElement() {

if (type_ == Type::JSON_OBJECT) {

JsonObject* object = value_.value_object;

for (auto& a : *object) {

delete a.second;

}

delete object;

}

else if (type_ == Type::JSON_ARRAY) {

JsonArray* array = value_.value_array;

for (auto& item : *array) {

delete item;

}

delete array;

}

else if (type_ == Type::JSON_STRING) {

std::string* val = value_.value_string;

delete val;

}

}

Type type() { return type_; }

void value(JsonObject* value) {

type_ = Type::JSON_OBJECT;

value_.value_object = value;

}

void value(JsonArray* value) {

type_ = Type::JSON_ARRAY;

value_.value_array = value;

}

void value(std::string* value) {

type_ = Type::JSON_STRING;

value_.value_string = value;

}

void value(float value) {

type_ = Type::JSON_NUMBER;

value_.value_number = value;

}

void value(bool value) {

type_ = Type::JSON_BOOL;

value_.value_bool = value;

}

JsonObject* AsObject() {

if (type_ == Type::JSON_OBJECT) {

return value_.value_object;

}

else {

Error("Type of JsonElement isn't JsonObject!");

return nullptr;

}

}

JsonArray* AsArray() {

if (type_ == Type::JSON_ARRAY) {

return value_.value_array;

}

else {

Error("Type of JsonElement isn't JsonArray!");

return nullptr;

}

}

std::string* AsString() {

if (type_ == Type::JSON_STRING) {

return value_.value_string;

}

else {

Error("Type of JsonElement isn't String!");

return nullptr;

}

}

float AsNumber() {

if (type_ == Type::JSON_NUMBER) {

return value_.value_number;

}

else {

Error("Type of JsonElement isn't Number!");

return 0.0f;

}

}

bool AsBoolean() {

if (type_ == Type::JSON_BOOL) {

return value_.value_bool;

}

else {

Error("Type of JsonElement isn't Boolean!");

return false;

}

}

std::string Dumps() {

std::stringstream ss;

switch (type_) {

case Type::JSON_OBJECT:

ss << *(value_.value_object);

break;

case Type::JSON_ARRAY:

ss << *(value_.value_array);

break;

case Type::JSON_STRING:

ss << '\"' << *(value_.value_string) << '\"';

break;

case Type::JSON_NUMBER:

ss << value_.value_number;

break;

case Type::JSON_BOOL:

ss << (value_.value_bool == true ? "true" : "false");

break;

case Type::JSON_NULL:

ss << "null";

break;

default:

break;

}

return ss.str();

}

friend std::ostream& operator<<(std::ostream& os, const JsonObject& object) {

os << "{";

for (auto iter = object.begin(); iter != object.end(); iter++) {

os << '\"' << iter->first << '\"' << ": " << iter->second->Dumps();

if (iter != --object.end()) {

os << ", ";

}

}

os << "}";

return os;

}

friend std::ostream& operator<<(std::ostream& os, const JsonArray& array) {

os << "[";

for (size_t i = 0; i < array.size(); i++) {

os << array[i]->Dumps();

if (i != array.size() - 1) {

os << ", ";

}

}

os << "]";

return os;

}

private:

Type type_;

Value value_;

};

} // namespace json

} // namespace Cliu

#pragma once

#include

#include"Error.h"

#include

namespace Cliu {

namespace json {

class Scanner {

public:

Scanner(const std::string& source) : source_(source), current_(0) {}

Scanner(std::string&& source) : source_(std::move(source)), current_(0) {}

enum class JsonTokenType

{

BEGIN_OBJECT, ///< {

END_OBJECT, ///< }

VALUE_SEPARATOR, ///< , 逗號

NAME_SEPARATOR, ///< : 冒號

VALUE_STRING, ///< "string"

VALUE_NUMBER, ///< 1,2,2e10

LITERAL_TRUE, ///< true

LITERAL_FALSE,///< false

LITERAL_NULL, ///< null

BEGIN_ARRAY, ///< [ 數(shù)組左括號

END_ARRAY, ///< ] 數(shù)組右括號

END_OF_SOURCE, ///< EOF

ERROR

};

JsonTokenType Scan(); // 掃描下一個,返回下一個token的type

void Rollback();

friend std::ostream& operator<<(std::ostream& os, const JsonTokenType& type) {

switch (type) {

case JsonTokenType::BEGIN_ARRAY:

os << "[";

break;

case JsonTokenType::END_ARRAY:

os << "]";

break;

case JsonTokenType::BEGIN_OBJECT:

os << "{";

break;

case JsonTokenType::END_OBJECT:

os << "}";

break;

case JsonTokenType::NAME_SEPARATOR:

os << ":";

break;

case JsonTokenType::VALUE_SEPARATOR:

os << ",";

break;

case JsonTokenType::VALUE_NUMBER:

os << "number";

break;

case JsonTokenType::VALUE_STRING:

os << "string";

break;

case JsonTokenType::LITERAL_TRUE:

os << "true";

break;

case JsonTokenType::LITERAL_FALSE:

os << "false";

break;

case JsonTokenType::LITERAL_NULL:

os << "null";

break;

case JsonTokenType::END_OF_SOURCE:

os << "EOF";

break;

default:

break;

}

return os;

}

float GetNumberValue() { return value_number_; };

const std::string& GetStringValue() { return value_string_; };

private:

bool IsAtEnd();

char Advance();

void ScanTrue();

void ScanFalse();

void ScanNull();

void ScanString();

void ScanNumber();

char Peek();

char PeekNext();

bool IsDigit(char c);

private:

std::string source_; ///< json source

size_t current_; ///< current pos of processing character

size_t prev_pos_; ///< previous handling pos;

float value_number_; ///< number value

std::string value_string_; ///< string value

};// end of class Scanner

} // namespace json

} // namespace Cliu

#include "Scanner.h"

namespace Cliu {

namespace json {

bool Scanner::IsAtEnd() {

return current_ >= source_.size();

}

char Scanner::Advance() {

return source_[current_++];

}

void Scanner::Rollback() { current_ = prev_pos_; }

bool Scanner::IsDigit(char c) { return c >= '0' && c <= '9'; }

char Scanner::Peek() { // 獲取下一個

if (IsAtEnd()) return '\0';

return source_[current_];

}

char Scanner::PeekNext() { // 要確保下一個值是存在的

if (current_ + 1 >= source_.size()) return '\0';

return source_[current_ + 1];

}

void Scanner::ScanTrue() { // 判斷是否是true

if (source_.compare(current_, 3, "rue") == 0) {

current_ += 3;

}

else {

Error("Scan `true` error");

}

}

void Scanner::ScanFalse() {

if (source_.compare(current_, 4, "alse") == 0) {

current_ += 4;

}

else {

Error("Scan `false` error");

}

}

void Scanner::ScanNull() {

if (source_.compare(current_, 3, "ull") == 0) {

current_ += 3;

}

else {

Error("Scan `null` error");

}

}

void Scanner::ScanString() {

size_t pos = current_;

while (Peek() != '\"' && !IsAtEnd()) {

Advance();// 再走一步 //沒有考慮轉(zhuǎn)義字符

}

if (IsAtEnd()) {

Error("invalid string: missing closing quote");

}

Advance();

value_string_ = source_.substr(pos, current_ - pos - 1);

}

void Scanner::ScanNumber() {

size_t pos = current_ - 1;

while (IsDigit(Peek())) {

Advance();

}

// fractional part

if (Peek() == '.' && IsDigit(PeekNext())) {

Advance();

while (IsDigit(Peek())) {

Advance();

}

}

value_number_ = std::atof(source_.substr(pos, current_ - pos).c_str());

}

Scanner::JsonTokenType Scanner::Scan()

{

// 判斷是否掃描完畢

if (IsAtEnd()) {

return JsonTokenType::END_OF_SOURCE; // 返回掃描完畢標識符

}

prev_pos_ = current_;

char c = Advance(); // 獲取下一個字符

switch (c)

{

case '[':

return JsonTokenType::BEGIN_ARRAY;

case ']':

return JsonTokenType::END_ARRAY;

case '{':

return JsonTokenType::BEGIN_OBJECT;

case '}':

return JsonTokenType::END_OBJECT;

case ':':

return JsonTokenType::NAME_SEPARATOR;

case ',':

return JsonTokenType::VALUE_SEPARATOR;

case 't':

ScanTrue();

return JsonTokenType::LITERAL_TRUE;

case 'f':

ScanFalse();

return JsonTokenType::LITERAL_FALSE;

case 'n':

ScanNull();

return JsonTokenType::LITERAL_NULL;

case '-':

case '0':

case '1':

case '2':

case '3':

case '4':

case '5':

case '6':

case '7':

case '8':

case '9':

ScanNumber();

return JsonTokenType::VALUE_NUMBER;

case '\"':

ScanString();

return JsonTokenType::VALUE_STRING;

case ' ':

case '\r':

case '\n':

case '\t':

return Scan();

default:

// error

std::string message = "Unsupported Token: ";

message += c;

Error(std::string(message));

return JsonTokenType::ERROR;

}

return JsonTokenType();

}

} // namespace json

} // namespace Cliu

#pragma once

#include"Scanner.h"

#include"JsonElement.h"

namespace Cliu {

namespace json {

class Parser {

using JsonTokenType = Scanner::JsonTokenType;

public:

JsonElement* Parse();

Parser(const Scanner& scanner) : scanner_(scanner) {}

private:

JsonObject* ParseObject();

JsonArray* ParseArray();

private:

Scanner scanner_;

};

} // namespace json

} // namespace Cliu

#include"Parser.h"

namespace Cliu {

namespace json {

JsonElement* Parser::Parse() {

JsonElement* element = new JsonElement();

JsonTokenType token_type_ = scanner_.Scan();

if (token_type_ != JsonTokenType::END_OF_SOURCE) {

switch (token_type_) {

case JsonTokenType::BEGIN_OBJECT: {

JsonObject* object = ParseObject();

element->value(object);

break;

}

case JsonTokenType::BEGIN_ARRAY: {

JsonArray* array = ParseArray();

element->value(array);

break;

}

case JsonTokenType::VALUE_STRING: {

std::string* val = new std::string(scanner_.GetStringValue());

element->value(val);

break;

}

case JsonTokenType::VALUE_NUMBER: {

element->value(scanner_.GetNumberValue());

break;

}

case JsonTokenType::LITERAL_TRUE: {

element->value(true);

break;

}

case JsonTokenType::LITERAL_FALSE: {

element->value(false);

break;

}

case JsonTokenType::LITERAL_NULL: {

break;

}

default:

break;

}

}

return element;

}

JsonObject* Parser::ParseObject() {

JsonObject* res = new JsonObject();

JsonTokenType next = scanner_.Scan();

if (next == JsonTokenType::END_OBJECT) { //判斷是否為空對象

return res;

}

scanner_.Rollback();// 回退一步

while (true) {

next = scanner_.Scan();

if (next != JsonTokenType::VALUE_STRING) {

Error("Key must be string!");

}

std::string key = scanner_.GetStringValue();

next = scanner_.Scan();

if (next != JsonTokenType::NAME_SEPARATOR) {

Error("Expected ':' in object!");

}

(*res)[key] = Parse();

next = scanner_.Scan();

if (next == JsonTokenType::END_OBJECT) {

break;

}

if (next != JsonTokenType::VALUE_SEPARATOR) {

Error("Expected ',' in object!");

}

}

return res;

}

JsonArray* Parser::ParseArray() {

JsonArray* res = new JsonArray();

JsonTokenType next = scanner_.Scan();

if (next == JsonTokenType::END_ARRAY) {

return res;

}

scanner_.Rollback();

while (true) {

res->push_back(Parse());

next = scanner_.Scan();

if (next == JsonTokenType::END_ARRAY) {

break;

}

if (next != JsonTokenType::VALUE_SEPARATOR) {

Error("Expected ',' in array!");

}

}

return res;

}

} // namespace json

} // namespace Cliu

參考列表 https://subingwen.cn/cpp/jsoncpp/?highlight=json https://blog.csdn.net/qq_43142808/article/details/115654942 https://zhuanlan.zhihu.com/p/476271291

柚子快報邀請碼778899分享:C++ JSON解析

http://yzkb.51969.com/

相關(guān)閱讀

評論可見,查看隱藏內(nèi)容

本文內(nèi)容根據(jù)網(wǎng)絡(luò)資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點和立場。

轉(zhuǎn)載請注明,如有侵權(quán),聯(lián)系刪除。

本文鏈接:http://m.gantiao.com.cn/post/19162214.html

發(fā)布評論

您暫未設(shè)置收款碼

請在主題配置——文章設(shè)置里上傳

掃描二維碼手機訪問

文章目錄