我是靠谱客的博主 光亮耳机,最近开发中收集的这篇文章主要介绍C++判断JSON字符串的合法性,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

写了一些,被证明有点非时间,不太符合业务的需求,留贴纪念吧。

json-format-check.h

#ifndef JSON_FORMAT_CHECK
#define JSON_FORMAT_CHECK

#include <iostream>
#include <string>

using namespace std;

class JsonString
{
public:
	typedef const char* Location;
	JsonString();

	/* 检测json字符串格式是否合法 */
	bool CheckFormat(const char *begin, const char *end);

private:
	enum TokenType
	{
		tokenEndOfStream = 0,
		tokenObjectBegin,
		tokenObjectEnd,
		tokenArrayBegin,
		tokenArrayEnd,
		tokenString,
		tokenNumber,
		tokenTrue,
		tokenFalse,
		tokenNull,
		tokenArraySeparator,
		tokenMemberSeparator,
		tokenError
	};

	class Token
	{
	public:
		TokenType type_;
	};

private:
	void SkipSpace();
	char GetNextChar();
	bool Match(Location pattern, int patternLength);
	bool ReadToken(Token &token);

	bool ReadString();
	void ReadNumber();
	bool ReadValue();
	bool ReadObject(Token &token);
	bool ReadArray(Token &token);

private:
	Location begin_;
	Location end_;
	Location current_;
	
	/* 用于记录对象的数量 */
	int objnum;
};

#endif	//JSON_FORMAT_CHECK

json-format-check.cpp

#include "json-format-check.h"

JsonString::JsonString()
{
	objnum = 0;
}

/* 验证json字符串的合法性 */
bool JsonString::CheckFormat(const char* strbegin, const char *strend)
{
	begin_   = strbegin;
	end_     = strend;
	current_ = begin_;

	bool succssful = ReadValue();
	if(objnum == 0)
	{
		return false;
	}
	return succssful;
}

/* 跳过空白字符 */
void JsonString::SkipSpace()
{
	while(current_ != end_)
	{
		char c = *current_;
		if(c == ' ' || c == 't' || c == 'r' || c == 'n')
		{
			++current_;
		}
		else
		{
			break;
		}
	}
}

/* 获得下一个字符 */
char JsonString::GetNextChar()
{
	if(current_ == end_)
	{
		return 0;
	}
	return *current_++;
}

/* 字符串匹配 */
bool JsonString::Match(Location pattern, int patternlength)
{
	if((end_ - current_) < patternlength )
	{
		return false;
	}
	int index = patternlength;
	while(index --)
	{
		if(current_[index] != pattern[index] )
		{
			return false;
		}
	}
	current_ += patternlength;
	return true;
}

/* 读取字符串 */
bool JsonString::ReadString()
{
	char c = 0;
	while(current_ != end_)
	{
		c= GetNextChar();
		if( c == '\')
		{
			c = GetNextChar();
		}
		else if( c == '"')
		{
			break;
		}
	}
	return (c == '"');
}

/* */
void JsonString::ReadNumber()
{
	while(current_ != end_)
	{
		if(!(*current_ >= '0' && *current_ <= '9')
			&& !(*current_ == '.' || *current_ == 'e'
			|| *current_ == 'E' || *current_ == '+'
			|| *current_ == '-'))
		{
			break;
		}
		++current_;
	}
}

bool JsonString::ReadToken( Token &token)
{
	SkipSpace();
	char c = GetNextChar();
	SkipSpace();
	if(c == ',' && *current_ == '}')
	{
		return false;
	}
	bool ok = true;

	switch(c)
	{
	case '{':
		token.type_ = tokenObjectBegin;
		break;
	case '}':
		token.type_ = tokenObjectEnd;
		break;
	case '[':
		token.type_ = tokenArrayBegin;
		break;
	case ']':
		token.type_ = tokenArrayEnd;
		break;
	case '"':
		token.type_ = tokenString;
		ok = ReadString();
		break;
	case '0':
	case '1':
	case '2':
	case '3':
	case '4':
	case '5':
	case '6':
	case '7':
	case '8':
	case '9':
	case '-':
		token.type_ = tokenNumber;
		ReadNumber();
		break;
	case 't':
		token.type_ = tokenTrue;
		ok = Match( "rue", 3 );
		break;
	case 'f':
		token.type_ = tokenFalse;
		ok = Match( "alse", 4 );
		break;
	case 'n':
		token.type_ = tokenNull;
		ok = Match( "ull", 3 );
		break;
	case ',':
		token.type_ = tokenArraySeparator;
		break;
	case ':':
		token.type_ = tokenMemberSeparator;
		break;
	case 0:
		token.type_ = tokenEndOfStream;
		break;
	default:
		ok = false;
		break;
	}
	if ( !ok )
		token.type_ = tokenError;
	return true;
}

bool JsonString::ReadObject(Token &tokenstart)
{
	Token tokenname;
	while(ReadToken(tokenname))
	{
		if(tokenname.type_ == tokenObjectEnd)
		{
			return true;
		}
		if(tokenname.type_ != tokenString)
		{
			break;
		}
		
		Token colon;
		if(!ReadToken(colon) || colon.type_ != tokenMemberSeparator)
		{
			return false;
		}
		bool ok = ReadValue();
		if(!ok)
		{
			return false;
		}

		Token comma;
		if(!ReadToken(comma) 
			||(comma.type_  != tokenObjectEnd 
			&& comma.type_ != tokenArraySeparator))
		{
			return false;
		}
		if(comma.type_ == tokenObjectEnd)
		{
			return true;
		}
	}
	return false;
}

bool JsonString::ReadArray(Token &tokenstart)
{
	SkipSpace();
	if(*current_ == ']')
	{
		Token endArray;
		ReadToken(endArray);
		return true;
	}
	
	int index = 0;
	while(true)
	{
		bool ok = ReadValue();
		if(!ok)
		{
			return false;
		}
		
		Token token;
		ok = ReadToken(token);
		
		bool badTokentype = 
			(token.type_ == tokenArraySeparator
			&& token.type_ == tokenArrayEnd);
		if( !ok & badTokentype)
		{
			return false;
		}
		if(token.type_ == tokenArrayEnd)
		{
			break;
		}
	}
	return true;
}

bool JsonString::ReadValue()
{
	Token token;
	ReadToken(token);
	bool successful = true;

	switch(token.type_)
	{
	case tokenObjectBegin:
		objnum++;
		successful = ReadObject(token);
		break;
	case tokenArrayBegin:
		successful = ReadArray(token);
		break;
	case tokenNumber:
	case tokenString:
	case tokenTrue:
	case tokenFalse:
	case tokenNull:
		break;
	default:
		return false;
	}
	return successful;
}


最后

以上就是光亮耳机为你收集整理的C++判断JSON字符串的合法性的全部内容,希望文章能够帮你解决C++判断JSON字符串的合法性所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(39)

评论列表共有 0 条评论

立即
投稿
返回
顶部