来自

从零开始的 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. 在他机上还原DB2的备份

    在服务器获取得到db2的备份文件,拷贝到d盘db2_backup目录下面 在windows下的时间戳标记为时间目录名+文件名.001前面的 "2014022\0001006.001" ...

  2. 0003 - 基于xml的Spring Bean 的创建过程

    一.目录 前言 创建 Bean 容器 加载 Bean 定义 创建 Bean Spring Bean 创建过程中的设计模式 总结 二.前言 2.1 Spring 使用配置 ApplicationCont ...

  3. 刘志梅 201771010115 《面向对象程序设计(java)》 第九周学习总结

    实验九 异常.断言与日志 实验时间 2018-10-25 1.实验目的与要求 (1) 程序中会出现的错误:用户输入错误.设备错误.代码错误.物理限制. 在Java程序设计语言中,异常对象都是派生于Th ...

  4. FlexItem 多行测试

    flex: <!doctype html> <html> <head> <meta charset="utf-8"> <tit ...

  5. python-web自动化-三种等待方式

    当有元素定位不到时,比如下拉框,弹出框等各种定位不到时:一般是两种问题:1 .有frame :2.没有加等待 下面学习三种等待方式: 1.强制等待 sleep(xx)这种方法简单粗暴,不管浏览器是否加 ...

  6. node和npm的安装和镜像源的修改

    在node官网下载https://nodejs.org/en/ 直接下载msi的文件,需要配置环境变量 我的电脑-->属性-->高级系统配置-->环境变量-->用户变量,在用户 ...

  7. javaee_正则表达式基础和常用表达式

    正则基础: 1.1 -字符集 [ ] : 代表单个字符. [^] : 除了该字符外的所有单个字符. [a-zA-Z] : [a-z] || [A-Z]. [a-d[m-p]] :[a, d] || [ ...

  8. Spring MVC和Spring Boot的理解以及比较

    Spring MVC是什么?(1)Spring MVC是Spring提供的一个强大而灵活的模块式web框架.通过Dispatcher Servlet, ModelAndView 和 View Reso ...

  9. leetcode114

    class Solution { public: void flatten(TreeNode* root) { while(root){ if(root->left){ TreeNode* pr ...

  10. C++ 日志生成 DLL

    示例: #define log_dbg(format,args...) \        printf("[DBG] [%s: %s() line:%d]: "format ,__ ...