来自

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

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

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

//JsonParse.h
#pragma once
#include "JsonStruct.h"
#include <assert.h> void DEFParseWhitespace(MyJsonStruct& js)
{
while (js.jsonStr[js.index] == ' ' ||
js.jsonStr[js.index] == '\r' ||
js.jsonStr[js.index] == '\n') {
js.index++;
}
} DefParseResult DEFParseNull(MyJsonStruct& js)
{
assert(js.jsonStr[js.index] = 'n');
if (js.jsonStr[js.index + 1] != 'u' ||
js.jsonStr[js.index+2] != 'l' ||
js.jsonStr[js.index+3] != 'l') {
return DEF_PARSE_INVALID_VALUE;
}
js.index += 4;
js.type = DEF_NULL;
return DEF_PARSE_OK;
} DefParseResult DEFParseValue(MyJsonStruct& js)
{
switch (js.jsonStr[js.index]){
case 'n':return DEFParseNull(js);
case '\0':return DEF_PARSE_EXPECT_VALUE;
default:return DEF_PARSE_INVALID_VALUE;
}
} DefParseType GetParseType(MyJsonStruct& js)
{
return js.type;
} void ResetJsonStruct(const char* jsonBuf, MyJsonStruct& js)
{
js.jsonStr = jsonBuf;
js.index = 0;
js.type = DEF_NONE;
} MyJsonStruct InitJsonStruct(char* jsonBuf)
{
MyJsonStruct jsonStruct;
ResetJsonStruct(jsonBuf, jsonStruct);
return jsonStruct;
} DefParseResult DEFParse(MyJsonStruct& jsonStruct)
{
DefParseResult ret; DEFParseWhitespace(jsonStruct); if ((ret = DEFParseValue(jsonStruct)) == DEF_PARSE_OK) {
DEFParseWhitespace(jsonStruct);
if (jsonStruct.index < jsonStruct.jsonStr.size()) {
ret = DEF_PARSE_ROOT_NOT_SINGULAR;
jsonStruct.type = DEF_NONE;
} }
return ret;
}

  

//JsonStruct.h
#pragma once
#include <string> enum DefParseType {
DEF_NONE,
DEF_NULL,
DEF_FALSE,
DEF_TRUE,
DEF_NUMBER,
DEF_STRING,
DEF_ARRAY,
DEF_OBJECT
}; struct MyJsonStruct {
std::string jsonStr;
size_t index;
DefParseType type;
}; enum DefParseResult{
DEF_PARSE_OK = 0,
DEF_PARSE_EXPECT_VALUE,
DEF_PARSE_INVALID_VALUE,
DEF_PARSE_ROOT_NOT_SINGULAR
};

  

//MyTestUnit.h
#pragma once
#include <iostream> 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_ = 0;
size_t MyTestClass::testPass_ = 0; #define ERROR_PRINT(expect,actual) \
std::cerr << __FILE__ <<":"<< __LINE__ << "\r\nexpect: " << expect << " actual: " << actual << std::endl; #define EXCEPT_EQ(expect, actual) \
do{ \
MyTestClass TEST; \
if(!TEST.ExceptEqual(expect, actual)){ \
ERROR_PRINT(expect,actual) \
} \
}while(0) #define PRINT_TEST_RESULT() \
do{ \
MyTestClass TEST; \
TEST.PrintResult(); \
}while(0)

  

// MyJson.cpp : 定义控制台应用程序的入口点。
// #include "stdafx.h"
#include "JsonParse.h"
#include <iostream>
#include "MyTestUnit.h" int main()
{
MyJsonStruct js =InitJsonStruct("null");
EXCEPT_EQ(DEF_PARSE_OK, DEFParse(js));
EXCEPT_EQ(DEF_NULL, GetParseType(js)); ResetJsonStruct("", js);
EXCEPT_EQ(DEF_PARSE_EXPECT_VALUE, DEFParse(js));
EXCEPT_EQ(DEF_NONE, GetParseType(js)); ResetJsonStruct(" ", js);
EXCEPT_EQ(DEF_PARSE_EXPECT_VALUE, DEFParse(js));
EXCEPT_EQ(DEF_NONE, GetParseType(js)); ResetJsonStruct("nul", js);
EXCEPT_EQ(DEF_PARSE_INVALID_VALUE, DEFParse(js));
EXCEPT_EQ(DEF_NONE, GetParseType(js)); ResetJsonStruct("?", js);
EXCEPT_EQ(DEF_PARSE_INVALID_VALUE, DEFParse(js));
EXCEPT_EQ(DEF_NONE, GetParseType(js)); ResetJsonStruct("null x", js);
EXCEPT_EQ(DEF_PARSE_ROOT_NOT_SINGULAR, DEFParse(js));
EXCEPT_EQ(DEF_NONE, GetParseType(js)); PRINT_TEST_RESULT();
return 0;
}

  测试效果

12/12 (100%) passed.
请按任意键继续. . .

最新文章

  1. HDU5863 cjj&#39;s string game(DP + 矩阵快速幂)
  2. 利用反射得到android存储路径
  3. UVALive 4043 Ants 蚂蚁(二分图最佳完美匹配,KM算法)
  4. calabash-android Win10 入门笔记
  5. node express
  6. NOIP
  7. (原)前端知识杂烩(css系列)
  8. hdu 2503 a/b + c/d
  9. CDONTS组件
  10. DDS视图&amp;Button控件
  11. python全栈学习--day2
  12. Android绘图机制(四)——使用HelloCharts开源框架搭建一系列炫酷图表,柱形图,折线图,饼状图和动画特效,抽丝剥茧带你认识图表之美
  13. NIO之FileChannel类的理解和使用
  14. apache服务Forbidden 403问题精彩总结
  15. BZOJ2749 HAOI2012外星人(数论)
  16. BZOJ4466 [Jsoi2013]超立方体
  17. 转 org.aspectj.lang.JoinPoint-中文简要API
  18. HTML IMG标签SRC为null
  19. Struts 2(四):类型转换
  20. Struts2---输入验证

热门文章

  1. IOCP之客户端及消息传递
  2. 使用 Windows AIK 创建自定的客户端系统WIM文件
  3. ThinkPad E440 Ubuntu 13.1无线网卡 RTL8723BE 驱动解决办法总结
  4. HBase体系结构(转)
  5. unity3d c#脚本定义Transform
  6. Symfony2 资料篇
  7. sudo用户管理
  8. vbs脚本要求在cmd中输入输出用StdIn ,StdOut
  9. [转载]: delphi中XLSReadWrite控件的使用(1)---简介
  10. 【转】Java八种基本数据类型的比较及其相互转化