状态机学习(六)解析JSON2
来自
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的更多相关文章
- 深入学习Python解析并解密PDF文件内容的方法
前面学习了解析PDF文档,并写入文档的知识,那篇文章的名字为深入学习Python解析并读取PDF文件内容的方法. 链接如下:https://www.cnblogs.com/wj-1314/p/9429 ...
- day 84 Vue学习六之axios、vuex、脚手架中组件传值
Vue学习六之axios.vuex.脚手架中组件传值 本节目录 一 axios的使用 二 vuex的使用 三 组件传值 四 xxx 五 xxx 六 xxx 七 xxx 八 xxx 一 axios的 ...
- Hbase深入学习(六) Java操作HBase
Hbase深入学习(六) ―― Java操作HBase 本文讲述如何用hbase shell命令和hbase java api对hbase服务器进行操作. 先看以下读取一行记录hbase是如何进行工作 ...
- TweenMax动画库学习(六)
目录 TweenMax动画库学习(一) TweenMax动画库学习(二) TweenMax动画库学习(三) Tw ...
- Delphi之通过代码示例学习XML解析、StringReplace的用法(异常控制 good)
*Delphi之通过代码示例学习XML解析.StringReplace的用法 这个程序可以用于解析任何合法的XML字符串. 首先是看一下程序的运行效果: 以解析这样一个XML的字符串为例: <? ...
- 分享非常有用的Java程序 (关键代码)(六)---解析/读取XML 文件(重要)
原文:分享非常有用的Java程序 (关键代码)(六)---解析/读取XML 文件(重要) XML文件 <?xml version="1.0"?> <student ...
- SVG 学习<六> SVG的transform
目录 SVG 学习<一>基础图形及线段 SVG 学习<二>进阶 SVG世界,视野,视窗 stroke属性 svg分组 SVG 学习<三>渐变 SVG 学习<四 ...
- C#多线程学习(六) 互斥对象
如何控制好多个线程相互之间的联系,不产生冲突和重复,这需要用到互斥对象,即:System.Threading 命名空间中的 Mutex 类. 我们可以把Mutex看作一个出租车,乘客看作线程.乘客首先 ...
- Unity学习(六)5.x依赖打包
http://blog.sina.com.cn/s/blog_89d90b7c0102w2ox.html unity5已经封装好了接口,所以依赖打包并没有那么神秘和复杂了. 打包: 1.定义好资源的a ...
- (转)MyBatis框架的学习(六)——MyBatis整合Spring
http://blog.csdn.net/yerenyuan_pku/article/details/71904315 本文将手把手教你如何使用MyBatis整合Spring,这儿,我本人使用的MyB ...
随机推荐
- 【RestTemplete】使用RestTemplete传Json或者 {} 报错--解决
https://jira.spring.io/browse/SPR-9220?focusedCommentId=76760&page=com.atlassian.jira.plugin.sys ...
- python数据处理 pandas用法大全
一.生成数据表 1.首先导入pandas库,一般都会用到numpy库,所以我们先导入备用: import numpy as np import pandas as pd 1 2 2.导入CSV ...
- Quartz的API简介及Jobs和Trigger介绍
Quartz的API: 主要api: The key interfaces of the Quartz API are: Scheduler - the main API for interactin ...
- Java内存列表
当jvm运行起来的时候,它会向系统申请一片内存区,并将这块内存分出一部分存储程序创建的对象,传递给方法的参数,返回值,局部变量等等,我们将这块内存称之为“运行时数据区”. 初学的时候把Java内存分为 ...
- HTML翻转菜单练习
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 用PS做圆角图片
ps: Adobe Photoshop CS2 如果图片被锁定,请“双击”图层中“背景”解锁,如果没有图层菜单,在最上面导航栏中:窗口—图层.如下图: 点“确定”,解锁. 选用“圆角矩形工具”. ...
- wepy 小程序云开发
小程序前段时间更新了云开发的功能,刚听到对时候觉得简直是个人开发者对福音,尤其是对我这样对后端不是很懂对前端傻傻,简直不能太方便,就试了下. 体验二维码: 源码:https://github.com/ ...
- 【Python】启动迅雷下载
import subprocess import base64 thunder_path = 'E:\Thunder\Program\Thunder.exe' def Url2Thunder(url) ...
- PHP响应码和HTTP请求方法
HTTP请求报文由请求行(request line).请求头部(header).空行和请求数据4个部分组成,格式如下 可见请求行由请求方法字段.URL字段和HTTP协议版本字段3个字段组成,它们用空格 ...
- 转载:c++深拷贝和浅拷贝
文章来自:http://blog.csdn.net/u010700335/article/details/39830425 C++中类的拷贝有两种:深拷贝,浅拷贝:当出现类的等号赋值时,即会调用拷贝函 ...