状态机学习(六)解析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 ...
随机推荐
- FluentData -Micro ORM with a fluent API that makes it simple to query a database 【MYSQL】
官方地址:http://fluentdata.codeplex.com/documentation MYSQL: MySQL through the MySQL Connector .NET driv ...
- globals和locals的区别
Python的两个内置函数,locals 和globals,它们提供了基于字典的访问局部和全局变量的方式. 1.locals()是只读的.globals()不是.这里说的只读,是值对于原有变量的只读. ...
- 20175227张雪莹 2018-2019-2 《Java程序设计》第三周学习总结
20175227张雪莹 2018-2019-2 <Java程序设计>第三周学习总结 教材学习内容总结 (仅在此列举个性化学习总结) 一.编程语言的几个发展阶段. 1.面向机器语言:汇编语言 ...
- [转] SQL日期函数dayadd/datediff/datepart
函数一: CREATE OR REPLACE FUNCTION dayadd(p_Component varchar2, p_Number number, p_Date date) RETURN DA ...
- (转)EF5+SQLserver2012迁移到EF6+mysql5.5.47
原文地址:https://www.cnblogs.com/tinyjian/p/6235014.html:https://www.cnblogs.com/tinyjian/p/6235397.html ...
- vuex教程,vuex使用介绍案例
1.demopageaction: import Vue from "vue"; import Store from "../../store.js"; imp ...
- 一个java使用redis的简单案例
这个例子中,java使用Jedis来操作Redis 1.引入Jedis的依赖 <dependency> <groupId>redis.clients</groupId&g ...
- BZOJ 3097: Hash Killer I
3097: Hash Killer I Time Limit: 5 Sec Memory Limit: 128 MBSec Special Judge[Submit][Status][Discus ...
- Springboot Download file
@RequestMapping(value = "/downloadSvt") public ResponseEntity<FileSystemResource> ex ...
- linux 获取帮助的命令
Linux命令详解:[7]获得命令帮助 听语音 | 浏览:4601 | 更新:2015-01-30 20:21 | 标签:linux 1 2 3 4 5 分步阅读 在维护和使用Linux系统时,常常会 ...