来自

从零开始的 JSON 库教程
从零开始教授如何写一个符合标准的 C 语言 JSON 库
作者 Milo Yip

https://zhuanlan.zhihu.com/json-tutorial

根据第二课教程 自己重新编写 做了一点修改 加深学习印象

这里写的有点随便 怎么方便怎么来

浮点的判断也是使用的函数 判断范围比json的要宽松些 仅作为练手练习使用

 #ifndef LEPTJSON_H
#define LEPTJSON_H
#include <string> enum DefParseResult{
DEF_PARSE_OK = ,
DEF_PARSE_EXPECT_VALUE,
DEF_PARSE_INVALID_VALUE,
DEF_PARSE_ROOT_NOT_SINGULAR
}; enum DefType {
DEF_NONE = ,
DEF_NULL,
DEF_FALSE,
DEF_TRUE,
DEF_NUMBER,
DEF_STRING,
DEF_ARRAY,
DEF_OBJECT
}; struct MyJsonStruct {
double d;
std::string jsonStr;
size_t index;
DefType type;
}; DefParseResult DefParse(MyJsonStruct& jstruct);
MyJsonStruct InitJsonStruct(char* str);
DefType GetJsonStructType( MyJsonStruct& jstruct);
double GetJsonStructNumber( MyJsonStruct& jstruct); #endif // LEPTJSON_H
 #include "leptjson.h"
#include <string>
#include <exception> void DefParseWhiteSpace(MyJsonStruct& jstruct)
{
if(jstruct.index == jstruct.jsonStr.size()-){
jstruct.index++;
return;
}
while( isspace(jstruct.jsonStr[jstruct.index])){
jstruct.index++;
}
} DefParseResult DefParseType(MyJsonStruct& jstruct){
if( jstruct.jsonStr[jstruct.index] == 'n'){
if(jstruct.jsonStr[jstruct.index+] == 'u' &&
jstruct.jsonStr[jstruct.index+] == 'l' &&
jstruct.jsonStr[jstruct.index+] == 'l')
{
jstruct.index += ;
jstruct.type = DEF_NULL;
return DEF_PARSE_OK;
} }else if(jstruct.jsonStr[jstruct.index] == 't'){
if(jstruct.jsonStr[jstruct.index+] == 'r' &&
jstruct.jsonStr[jstruct.index+] == 'u' &&
jstruct.jsonStr[jstruct.index+] == 'e')
{
jstruct.index += ;
jstruct.type = DEF_TRUE;
return DEF_PARSE_OK;
}
}else if(jstruct.jsonStr[jstruct.index] == 'f'){
if(jstruct.jsonStr[jstruct.index+] == 'a' &&
jstruct.jsonStr[jstruct.index+] == 'l' &&
jstruct.jsonStr[jstruct.index+] == 's' &&
jstruct.jsonStr[jstruct.index+] == 'e')
{
jstruct.index += ;
jstruct.type = DEF_FALSE;
return DEF_PARSE_OK;
}
} return DEF_PARSE_INVALID_VALUE;
} #define ISDIGIT(ch) ((ch) >= '0' && (ch) <= '9')
#define ISDIGIT1TO9(ch) ((ch) >= '1' && (ch) <= '9')
DefParseResult DefParseNumber(MyJsonStruct& jstruct)
{
try{
jstruct.d = std::stod(jstruct.jsonStr);
jstruct.index = jstruct.jsonStr.find_first_of("\t\r\n ");
}catch(std::exception& e){
return DEF_PARSE_INVALID_VALUE;
} jstruct.type = DEF_NUMBER; return DEF_PARSE_OK;
} DefParseResult DefParseValue(MyJsonStruct& jstruct)
{
if(jstruct.index > jstruct.jsonStr.size())
return DEF_PARSE_INVALID_VALUE;
switch(jstruct.jsonStr[jstruct.index]){
case 'n':
case 'f':
case 't':
return DefParseType(jstruct);
default:
return DefParseNumber(jstruct);
}
} MyJsonStruct InitJsonStruct(char* str){
if(str == nullptr){
return MyJsonStruct{0.0,NULL,NULL,DEF_NONE};
} return MyJsonStruct{0.0,str,,DEF_NONE};
} DefType GetJsonStructType( MyJsonStruct& jstruct){
return jstruct.type;
} double GetJsonStructNumber( MyJsonStruct& jstruct)
{
return jstruct.d;
} DefParseResult DefParse(MyJsonStruct& jstruct)
{
DefParseResult ret = DEF_PARSE_INVALID_VALUE;
DefParseWhiteSpace(jstruct); ret = DefParseValue(jstruct);
if(ret != DEF_PARSE_OK){
return ret;
} DefParseWhiteSpace(jstruct);
if(jstruct.index < jstruct.jsonStr.size()){
ret = DEF_PARSE_ROOT_NOT_SINGULAR;
jstruct.type = DEF_NONE;
} return ret;
}
 #include <iostream>
#include "leptjson.h" class MyTestClass {
static size_t testCount_;
static size_t testPass_;
public:
template<typename E,typename A>
bool ExceptEqual(E e, A a)
{
testCount_++;
if (e == a){
testPass_++;
return true;
}
return false;
} void PrintResult(){
std::cout << testPass_ << "/" << testCount_ << "\t" << "("<<(testPass_ * 100.0 / testCount_) << "%)" << " passed." << std::endl;
}
};
size_t MyTestClass::testCount_ = ;
size_t MyTestClass::testPass_ = ; #define ERROR_PRINT(expect,actual) \
std::cerr << __FILE__ <<":"<< __LINE__ << "\r\nexpect: " << expect << " actual: " << actual << std::endl; #define EXPECT_EQ(expect, actual) \
do{ \
MyTestClass TEST; \
if(!TEST.ExceptEqual(expect, actual)){ \
ERROR_PRINT(expect,actual) \
} \
}while() #define PRINT_TEST_RESULT() \
do{ \
MyTestClass TEST; \
TEST.PrintResult(); \
}while()
//=======================================================================
using namespace std; static void TestParseNULL(){
MyJsonStruct jsonStruct = InitJsonStruct("null");
EXPECT_EQ(DEF_PARSE_OK,DefParse(jsonStruct));
EXPECT_EQ(DEF_NULL, GetJsonStructType(jsonStruct));
} static void TestParseTRUE(){
MyJsonStruct jsonStruct = InitJsonStruct("true");
EXPECT_EQ(DEF_PARSE_OK,DefParse(jsonStruct));
EXPECT_EQ(DEF_TRUE, GetJsonStructType(jsonStruct));
} static void TestParseFALSE(){
MyJsonStruct jsonStruct = InitJsonStruct("false");
EXPECT_EQ(DEF_PARSE_OK,DefParse(jsonStruct));
EXPECT_EQ(DEF_FALSE, GetJsonStructType(jsonStruct));
} #define TEST_ERROR(error, json)\
do {\
MyJsonStruct jsonStruct = InitJsonStruct(json);\
EXPECT_EQ(error, DefParse(jsonStruct));\
EXPECT_EQ(DEF_NONE, GetJsonStructType(jsonStruct));\
} while() static void TestParseInvaliValue(){
TEST_ERROR(DEF_PARSE_INVALID_VALUE,"nul");
TEST_ERROR(DEF_PARSE_INVALID_VALUE,"?"); TEST_ERROR(DEF_PARSE_INVALID_VALUE,"nul");
TEST_ERROR(DEF_PARSE_INVALID_VALUE,"?"); } static void TestParseRootNotSingular(){
MyJsonStruct jsonStruct = InitJsonStruct("null x");
EXPECT_EQ(DEF_PARSE_ROOT_NOT_SINGULAR, DefParse(jsonStruct));
EXPECT_EQ(DEF_NONE, GetJsonStructType(jsonStruct));
} #define TEST_NUMBER(expect, json)\
do {\
MyJsonStruct jsonStruct = InitJsonStruct(json); \
EXPECT_EQ(DEF_PARSE_OK, DefParse(jsonStruct));\
EXPECT_EQ(DEF_NUMBER, GetJsonStructType(jsonStruct));\
EXPECT_EQ(expect, GetJsonStructNumber(jsonStruct));\
} while() static void TestParseNumber(){
TEST_NUMBER(0.0, "");
TEST_NUMBER(0.0, "-0");
TEST_NUMBER(0.0, "-0.0");
TEST_NUMBER(1.0, "");
TEST_NUMBER(-1.0, "-1");
TEST_NUMBER(1.5, "1.5");
TEST_NUMBER(-1.5, "-1.5");
TEST_NUMBER(3.1416, "3.1416");
TEST_NUMBER(1E10, "1E10");
TEST_NUMBER(1e10, "1e10");
TEST_NUMBER(1E+, "1E+10");
TEST_NUMBER(1E-, "1E-10");
TEST_NUMBER(-1E10, "-1E10");
TEST_NUMBER(-1e10, "-1e10");
TEST_NUMBER(-1E+, "-1E+10");
TEST_NUMBER(-1E-, "-1E-10");
TEST_NUMBER(1.234E+10, "1.234E+10");
TEST_NUMBER(1.234E-10, "1.234E-10"); TEST_NUMBER(1.0000000000000002, "1.0000000000000002"); /* the smallest number > 1 */
TEST_NUMBER( 2.2250738585072014e-308, "2.2250738585072014e-308"); /* Min normal positive double */
TEST_NUMBER(-2.2250738585072014e-308, "-2.2250738585072014e-308");
TEST_NUMBER( 1.7976931348623157e+308, "1.7976931348623157e+308"); /* Max double */
TEST_NUMBER(-1.7976931348623157e+308, "-1.7976931348623157e+308");
} void TestParse()
{
TestParseNULL();
TestParseTRUE();
TestParseFALSE();
TestParseInvaliValue();
TestParseRootNotSingular();
TestParseNumber();
} int main(int argc, char *argv[])
{
TestParse();
PRINT_TEST_RESULT();
return ;
}

显示结果

状态机学习(六)解析JSON2的更多相关文章

  1. 深入学习Python解析并解密PDF文件内容的方法

    前面学习了解析PDF文档,并写入文档的知识,那篇文章的名字为深入学习Python解析并读取PDF文件内容的方法. 链接如下:https://www.cnblogs.com/wj-1314/p/9429 ...

  2. day 84 Vue学习六之axios、vuex、脚手架中组件传值

    Vue学习六之axios.vuex.脚手架中组件传值   本节目录 一 axios的使用 二 vuex的使用 三 组件传值 四 xxx 五 xxx 六 xxx 七 xxx 八 xxx 一 axios的 ...

  3. Hbase深入学习(六) Java操作HBase

    Hbase深入学习(六) ―― Java操作HBase 本文讲述如何用hbase shell命令和hbase java api对hbase服务器进行操作. 先看以下读取一行记录hbase是如何进行工作 ...

  4. TweenMax动画库学习(六)

    目录            TweenMax动画库学习(一)            TweenMax动画库学习(二)            TweenMax动画库学习(三)            Tw ...

  5. Delphi之通过代码示例学习XML解析、StringReplace的用法(异常控制 good)

    *Delphi之通过代码示例学习XML解析.StringReplace的用法 这个程序可以用于解析任何合法的XML字符串. 首先是看一下程序的运行效果: 以解析这样一个XML的字符串为例: <? ...

  6. 分享非常有用的Java程序 (关键代码)(六)---解析/读取XML 文件(重要)

    原文:分享非常有用的Java程序 (关键代码)(六)---解析/读取XML 文件(重要) XML文件 <?xml version="1.0"?> <student ...

  7. SVG 学习<六> SVG的transform

    目录 SVG 学习<一>基础图形及线段 SVG 学习<二>进阶 SVG世界,视野,视窗 stroke属性 svg分组 SVG 学习<三>渐变 SVG 学习<四 ...

  8. C#多线程学习(六) 互斥对象

    如何控制好多个线程相互之间的联系,不产生冲突和重复,这需要用到互斥对象,即:System.Threading 命名空间中的 Mutex 类. 我们可以把Mutex看作一个出租车,乘客看作线程.乘客首先 ...

  9. Unity学习(六)5.x依赖打包

    http://blog.sina.com.cn/s/blog_89d90b7c0102w2ox.html unity5已经封装好了接口,所以依赖打包并没有那么神秘和复杂了. 打包: 1.定义好资源的a ...

  10. (转)MyBatis框架的学习(六)——MyBatis整合Spring

    http://blog.csdn.net/yerenyuan_pku/article/details/71904315 本文将手把手教你如何使用MyBatis整合Spring,这儿,我本人使用的MyB ...

随机推荐

  1. ubuntu彻底卸载opencv

    说正事之前,先啰嗦两句背景,算是拿个小本本记下了. 我本打算下载opencv2.4.在github上找到源码,在Branch处选择切换到2.4,然后复制URL,在terminal里面使用git clo ...

  2. 关于Verilog中begin-end & fork-join

     转载:http://blog.sina.com.cn/s/blog_6c7b6f030101cpgt.html begin-end and fork-join are used to combi ...

  3. mysqlbinlog基于时间点恢复

    基于时间点恢复 /data/mysq/mysqlbin.000026 #mysqlbinlog文件,恢复如下内容: 注意:按照时间点恢复时,可能同一个时间点有其他的操作,要结合上下文的时间选取~ # ...

  4. Webservices部署在IIS6.0上的一个小问题

    部署方式还是跟网站的部署方式一样,可是通过localhost访问一直提示400(bad request)错误. 可以在iis上预览到.在vs上引用的时候怎么都预览不到. 换个思路,把localhost ...

  5. kafka的log存储解析——topic的分区partition分段segment以及索引等(转发)

    原文 https://www.cnblogs.com/dorothychai/p/6181058.html 引言 Kafka中的Message是以topic为基本单位组织的,不同的topic之间是相互 ...

  6. dns缓存刷新时间是多久?dns本地缓存时间介绍

    原文: http://www.winwin7.com/JC/4742.html dns缓存刷新时间是多久?一般来说,我们只知道DNS解析是互联网绝大多数应用的实际寻址方式,在我们打开某站点,DNS返回 ...

  7. android 开发 View _9_ 实现渐变功能(直线与圆形)

    参考博客:https://blog.csdn.net/iispring/article/details/50500106/ android颜色渐变的分类有: LinearGradient线性渐变 线性 ...

  8. leetcode206

    /** * Definition for singly-linked list. * public class ListNode { * public int val; * public ListNo ...

  9. Javascript面试题收集

    第一部分“ 来源: http://bbs.miaov.com/forum.php?mod=viewthread&tid=6974 1.var a = b = 1; ——这样定义变量的隐患 fu ...

  10. javaScript+html5实现图片拖拽

    源码: <!DOCTYPE html><html><head> <meta charset="utf-8"/> <title& ...