状态机学习(六)解析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 ...
随机推荐
- 在他机上还原DB2的备份
在服务器获取得到db2的备份文件,拷贝到d盘db2_backup目录下面 在windows下的时间戳标记为时间目录名+文件名.001前面的 "2014022\0001006.001" ...
- 0003 - 基于xml的Spring Bean 的创建过程
一.目录 前言 创建 Bean 容器 加载 Bean 定义 创建 Bean Spring Bean 创建过程中的设计模式 总结 二.前言 2.1 Spring 使用配置 ApplicationCont ...
- 刘志梅 201771010115 《面向对象程序设计(java)》 第九周学习总结
实验九 异常.断言与日志 实验时间 2018-10-25 1.实验目的与要求 (1) 程序中会出现的错误:用户输入错误.设备错误.代码错误.物理限制. 在Java程序设计语言中,异常对象都是派生于Th ...
- FlexItem 多行测试
flex: <!doctype html> <html> <head> <meta charset="utf-8"> <tit ...
- python-web自动化-三种等待方式
当有元素定位不到时,比如下拉框,弹出框等各种定位不到时:一般是两种问题:1 .有frame :2.没有加等待 下面学习三种等待方式: 1.强制等待 sleep(xx)这种方法简单粗暴,不管浏览器是否加 ...
- node和npm的安装和镜像源的修改
在node官网下载https://nodejs.org/en/ 直接下载msi的文件,需要配置环境变量 我的电脑-->属性-->高级系统配置-->环境变量-->用户变量,在用户 ...
- javaee_正则表达式基础和常用表达式
正则基础: 1.1 -字符集 [ ] : 代表单个字符. [^] : 除了该字符外的所有单个字符. [a-zA-Z] : [a-z] || [A-Z]. [a-d[m-p]] :[a, d] || [ ...
- Spring MVC和Spring Boot的理解以及比较
Spring MVC是什么?(1)Spring MVC是Spring提供的一个强大而灵活的模块式web框架.通过Dispatcher Servlet, ModelAndView 和 View Reso ...
- leetcode114
class Solution { public: void flatten(TreeNode* root) { while(root){ if(root->left){ TreeNode* pr ...
- C++ 日志生成 DLL
示例: #define log_dbg(format,args...) \ printf("[DBG] [%s: %s() line:%d]: "format ,__ ...