来自
从零开始的 JSON 库教程
从零开始教授如何写一个符合标准的 C 语言 JSON 库
作者
Milo Yip
https://zhuanlan.zhihu.com/json-tutorial
根据第二课教程 自己重新编写 做了一点修改 加深学习印象
这里写的有点随便 怎么方便怎么来
浮点的判断也是使用的函数 判断范围比json的要宽松些 仅作为练手练习使用
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #ifndef LEPTJSON_H 2 #define LEPTJSON_H 3 #include <string> 4 5 6 7 8 enum DefParseResult{ 9 DEF_PARSE_OK = 0, 10 DEF_PARSE_EXPECT_VALUE, 11 DEF_PARSE_INVALID_VALUE, 12 DEF_PARSE_ROOT_NOT_SINGULAR 13 }; 14 15 enum DefType { 16 DEF_NONE = 0, 17 DEF_NULL, 18 DEF_FALSE, 19 DEF_TRUE, 20 DEF_NUMBER, 21 DEF_STRING, 22 DEF_ARRAY, 23 DEF_OBJECT 24 }; 25 26 struct MyJsonStruct { 27 double d; 28 std::string jsonStr; 29 size_t index; 30 DefType type; 31 }; 32 33 34 DefParseResult DefParse(MyJsonStruct& jstruct); 35 MyJsonStruct InitJsonStruct(char* str); 36 DefType GetJsonStructType( MyJsonStruct& jstruct); 37 double GetJsonStructNumber( MyJsonStruct& jstruct); 38 39 #endif // LEPTJSON_H
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #include "leptjson.h" 2 #include <string> 3 #include <exception> 4 5 void DefParseWhiteSpace(MyJsonStruct& jstruct) 6 { 7 if(jstruct.index == jstruct.jsonStr.size()-1){ 8 jstruct.index++; 9 return; 10 } 11 while( isspace(jstruct.jsonStr[jstruct.index])){ 12 jstruct.index++; 13 } 14 } 15 16 DefParseResult DefParseType(MyJsonStruct& jstruct){ 17 if( jstruct.jsonStr[jstruct.index] == 'n'){ 18 if(jstruct.jsonStr[jstruct.index+1] == 'u' && 19 jstruct.jsonStr[jstruct.index+2] == 'l' && 20 jstruct.jsonStr[jstruct.index+3] == 'l') 21 { 22 jstruct.index += 4; 23 jstruct.type = DEF_NULL; 24 return DEF_PARSE_OK; 25 } 26 27 }else if(jstruct.jsonStr[jstruct.index] == 't'){ 28 if(jstruct.jsonStr[jstruct.index+1] == 'r' && 29 jstruct.jsonStr[jstruct.index+2] == 'u' && 30 jstruct.jsonStr[jstruct.index+3] == 'e') 31 { 32 jstruct.index += 4; 33 jstruct.type = DEF_TRUE; 34 return DEF_PARSE_OK; 35 } 36 }else if(jstruct.jsonStr[jstruct.index] == 'f'){ 37 if(jstruct.jsonStr[jstruct.index+1] == 'a' && 38 jstruct.jsonStr[jstruct.index+2] == 'l' && 39 jstruct.jsonStr[jstruct.index+3] == 's' && 40 jstruct.jsonStr[jstruct.index+4] == 'e') 41 { 42 jstruct.index += 5; 43 jstruct.type = DEF_FALSE; 44 return DEF_PARSE_OK; 45 } 46 } 47 48 return DEF_PARSE_INVALID_VALUE; 49 } 50 51 #define ISDIGIT(ch) ((ch) >= '0' && (ch) <= '9') 52 #define ISDIGIT1TO9(ch) ((ch) >= '1' && (ch) <= '9') 53 DefParseResult DefParseNumber(MyJsonStruct& jstruct) 54 { 55 try{ 56 jstruct.d = std::stod(jstruct.jsonStr); 57 jstruct.index = jstruct.jsonStr.find_first_of("\t\r\n "); 58 }catch(std::exception& e){ 59 return DEF_PARSE_INVALID_VALUE; 60 } 61 62 jstruct.type = DEF_NUMBER; 63 64 return DEF_PARSE_OK; 65 } 66 67 DefParseResult DefParseValue(MyJsonStruct& jstruct) 68 { 69 if(jstruct.index > jstruct.jsonStr.size()) 70 return DEF_PARSE_INVALID_VALUE; 71 switch(jstruct.jsonStr[jstruct.index]){ 72 case 'n': 73 case 'f': 74 case 't': 75 return DefParseType(jstruct); 76 default: 77 return DefParseNumber(jstruct); 78 } 79 } 80 81 MyJsonStruct InitJsonStruct(char* str){ 82 if(str == nullptr){ 83 return MyJsonStruct{0.0,NULL,NULL,DEF_NONE}; 84 } 85 86 return MyJsonStruct{0.0,str,0,DEF_NONE}; 87 } 88 89 DefType GetJsonStructType( MyJsonStruct& jstruct){ 90 return jstruct.type; 91 } 92 93 double GetJsonStructNumber( MyJsonStruct& jstruct) 94 { 95 return jstruct.d; 96 } 97 98 DefParseResult DefParse(MyJsonStruct& jstruct) 99 { 100 DefParseResult ret = DEF_PARSE_INVALID_VALUE; 101 DefParseWhiteSpace(jstruct); 102 103 ret = DefParseValue(jstruct); 104 if(ret != DEF_PARSE_OK){ 105 return ret; 106 } 107 108 DefParseWhiteSpace(jstruct); 109 if(jstruct.index < jstruct.jsonStr.size()){ 110 ret = DEF_PARSE_ROOT_NOT_SINGULAR; 111 jstruct.type = DEF_NONE; 112 } 113 114 return ret; 115 }
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #include <iostream> 2 #include "leptjson.h" 3 4 class MyTestClass { 5 static size_t testCount_; 6 static size_t testPass_; 7 public: 8 template<typename E,typename A> 9 bool ExceptEqual(E e, A a) 10 { 11 testCount_++; 12 if (e == a){ 13 testPass_++; 14 return true; 15 } 16 return false; 17 } 18 19 void PrintResult(){ 20 std::cout << testPass_ << "/" << testCount_ << "\t" << "("<<(testPass_ * 100.0 / testCount_) << "%)" << " passed." << std::endl; 21 } 22 }; 23 size_t MyTestClass::testCount_ = 0; 24 size_t MyTestClass::testPass_ = 0; 25 26 #define ERROR_PRINT(expect,actual) \ 27 std::cerr << __FILE__ <<":"<< __LINE__ << "\r\nexpect: " << expect << " actual: " << actual << std::endl; 28 29 #define EXPECT_EQ(expect, actual) \ 30 do{ \ 31 MyTestClass TEST; \ 32 if(!TEST.ExceptEqual(expect, actual)){ \ 33 ERROR_PRINT(expect,actual) \ 34 } \ 35 }while(0) 36 37 #define PRINT_TEST_RESULT() \ 38 do{ \ 39 MyTestClass TEST; \ 40 TEST.PrintResult(); \ 41 }while(0) 42 //======================================================================= 43 using namespace std; 44 45 static void TestParseNULL(){ 46 MyJsonStruct jsonStruct = InitJsonStruct("null"); 47 EXPECT_EQ(DEF_PARSE_OK,DefParse(jsonStruct)); 48 EXPECT_EQ(DEF_NULL, GetJsonStructType(jsonStruct)); 49 } 50 51 static void TestParseTRUE(){ 52 MyJsonStruct jsonStruct = InitJsonStruct("true"); 53 EXPECT_EQ(DEF_PARSE_OK,DefParse(jsonStruct)); 54 EXPECT_EQ(DEF_TRUE, GetJsonStructType(jsonStruct)); 55 } 56 57 static void TestParseFALSE(){ 58 MyJsonStruct jsonStruct = InitJsonStruct("false"); 59 EXPECT_EQ(DEF_PARSE_OK,DefParse(jsonStruct)); 60 EXPECT_EQ(DEF_FALSE, GetJsonStructType(jsonStruct)); 61 } 62 63 #define TEST_ERROR(error, json)\ 64 do {\ 65 MyJsonStruct jsonStruct = InitJsonStruct(json);\ 66 EXPECT_EQ(error, DefParse(jsonStruct));\ 67 EXPECT_EQ(DEF_NONE, GetJsonStructType(jsonStruct));\ 68 } while(0) 69 70 static void TestParseInvaliValue(){ 71 TEST_ERROR(DEF_PARSE_INVALID_VALUE,"nul"); 72 TEST_ERROR(DEF_PARSE_INVALID_VALUE,"?"); 73 74 TEST_ERROR(DEF_PARSE_INVALID_VALUE,"nul"); 75 TEST_ERROR(DEF_PARSE_INVALID_VALUE,"?"); 76 77 } 78 79 static void TestParseRootNotSingular(){ 80 MyJsonStruct jsonStruct = InitJsonStruct("null x"); 81 EXPECT_EQ(DEF_PARSE_ROOT_NOT_SINGULAR, DefParse(jsonStruct)); 82 EXPECT_EQ(DEF_NONE, GetJsonStructType(jsonStruct)); 83 } 84 85 86 87 88 #define TEST_NUMBER(expect, json)\ 89 do {\ 90 MyJsonStruct jsonStruct = InitJsonStruct(json); \ 91 EXPECT_EQ(DEF_PARSE_OK, DefParse(jsonStruct));\ 92 EXPECT_EQ(DEF_NUMBER, GetJsonStructType(jsonStruct));\ 93 EXPECT_EQ(expect, GetJsonStructNumber(jsonStruct));\ 94 } while(0) 95 96 97 static void TestParseNumber(){ 98 TEST_NUMBER(0.0, "0"); 99 TEST_NUMBER(0.0, "-0"); 100 TEST_NUMBER(0.0, "-0.0"); 101 TEST_NUMBER(1.0, "1"); 102 TEST_NUMBER(-1.0, "-1"); 103 TEST_NUMBER(1.5, "1.5"); 104 TEST_NUMBER(-1.5, "-1.5"); 105 TEST_NUMBER(3.1416, "3.1416"); 106 TEST_NUMBER(1E10, "1E10"); 107 TEST_NUMBER(1e10, "1e10"); 108 TEST_NUMBER(1E+10, "1E+10"); 109 TEST_NUMBER(1E-10, "1E-10"); 110 TEST_NUMBER(-1E10, "-1E10"); 111 TEST_NUMBER(-1e10, "-1e10"); 112 TEST_NUMBER(-1E+10, "-1E+10"); 113 TEST_NUMBER(-1E-10, "-1E-10"); 114 TEST_NUMBER(1.234E+10, "1.234E+10"); 115 TEST_NUMBER(1.234E-10, "1.234E-10"); 116 117 118 TEST_NUMBER(1.0000000000000002, "1.0000000000000002"); /* the smallest number > 1 */ 119 TEST_NUMBER( 2.2250738585072014e-308, "2.2250738585072014e-308"); /* Min normal positive double */ 120 TEST_NUMBER(-2.2250738585072014e-308, "-2.2250738585072014e-308"); 121 TEST_NUMBER( 1.7976931348623157e+308, "1.7976931348623157e+308"); /* Max double */ 122 TEST_NUMBER(-1.7976931348623157e+308, "-1.7976931348623157e+308"); 123 } 124 125 126 void TestParse() 127 { 128 TestParseNULL(); 129 TestParseTRUE(); 130 TestParseFALSE(); 131 TestParseInvaliValue(); 132 TestParseRootNotSingular(); 133 TestParseNumber(); 134 } 135 136 137 138 139 int main(int argc, char *argv[]) 140 { 141 TestParse(); 142 PRINT_TEST_RESULT(); 143 return 0; 144 }
显示结果