解析json字符串

说明

这个是基于我的使用需求,所以在打印输出信息上面有些删减。解析是完整的,可以根据你的需求自己打印。
没有使用堆,没有树,使用了递归(解析json数组部分)和循环(json对象嵌套部分),适用于嵌入式上面 节约内存开销,避免动态开辟内存的一系列问题。
还有部分特殊情况没有做处理,在数组中字符串中出现[]{}"等符号。其他的可能就是bug吧。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define TEST_ENABLED 0
#define MODEL_ENABLED(model) ((defined(model##_ENABLED) && (model##_ENABLED)) ? 1 : 0)
char text1[] = "{\"title\":{\"text\":\"\"},\"tooltip\":{\"trigger\":\"axis\"},\"legend\":{\"data\":[\"email\",\"ad\",\"video\",\"access\",\"search\"]},\"grid\":{\"left\":\"3%\",\"right\":\"4%\",\"bottom\":\"3%\",\"containLabel\":true},\"toolbox\":{\"feature\":{\"saveAsImage\":{\"ss\":\"aa\"}}},\"xAxis\":{\"type\":\"category\",\"boundaryGap\":false,\"data\":[\"Mon\",\"Tue\",\"Wed\",\"Thu\",\"Fri\",\"Sat\",\"Sun\"]},\"yAxis\":{\"type\":\"value\"},\"series\":[{\"name\":\"email\",\"type\":\"line\",\"stack\":\"summer\",\"data\":[120,132,101,134,90,230,210]},{\"name\":\"ad\",\"type\":\"line\",\"stack\":\"summer\",\"data\":[220,182,191,234,290,330,310]},{\"name\":\"video\",\"type\":\"line\",\"stack\":\"summer\",\"data\":[150,232,201,154,190,330,410]}]}";
char text2[] = "{\
	\"title\": {\
		\"text\": \"\"\
	},\
	\"tooltip\": {\
		\"trigger\": \"axis\"\
	},\
	\"legend\": {\
		\"data\": [\"email\", \"ad\", \"video\", \"access\", \"search\"]\
	},\
	\"grid\": {\
		\"left\": \"3%\",\
		\"right\": \"4%\",\
		\"bottom\": \"3%\",\
		\"containLabel\": true\
	},\
	\"toolbox\": {\
		\"feature\": {\
			\"saveAsImage\": {\
				\"ss\": \"aa\"\
			}\
		}\
	},\
	\"xAxis\": {\
		\"type\": \"category\",\
		\"boundaryGap\": false,\
		\"data\": [\"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\", \"Sun\"]\
	},\
	\"yAxis\": {\
		\"type\": \"value\"\
	},\
	\"series\": {\
		\"name\": \"email\",\
		\"type\": \"line\",\
		\"stack\": \"summer\",\
		\"data\": [120, 132, 101, 134, 90, 230, 210]\
	}\
}";
char text3[] = "{\"title\":{\"text\":\"zhexian\"},\"tooltip\":{\"trigger\":\"axis\"},\"legend\":{\"data\":[\"email\",\"ad\",\"video\",\"access\",\"search\"]},\"grid\":{\"left\":\"3%\",\"right\":\"4%\",\"bottom\":\"3%\",\"containLabel\":true},\"toolbox\":{\"feature\":{\"saveAsImage\":{\"ss\":\"aa\"}}},\"xAxis\":{\"type\":\"category\",\"boundaryGap\":false,\"data\":[\"Mon\",\"Tue\",\"Wed\",\"Thu\",\"Fri\",\"Sat\",\"Sun\"]},\"yAxis\":{\"type\":\"value\"},\"series\":[{\"name\":\"email\",\"type\":\"line\",\"stack\":\"summer\",\"data\":[120,132,101,134,90,230,210]},{\"name\":\"ad\",\"type\":\"line\",\"stack\":\"summer\",\"data\":[220,182,191,234,290,330,310]},{\"name\":\"video\",\"type\":\"line\",\"stack\":\"summer\",\"data\":[150,232,201,154,190,330,410]}]}";
char text4[] = "{\n		\"Image\": {\n			\"Width\":  800,\n			\"Height\": 600,\n			\"Title\":  \"View from 15th Floor\",\n			\"Thumbnail\": {\n				\"Url\":    \"http:/*www.example.com/image/481989943\",\n				\"Height\": 125,\n				\"Width\":  \"100\"\n			},\n			\"IDs\": [116, 943, 234, 38793]\n		}\n	}";
char text5[] = "[\n	 {\n	 \"precision\": \"zip\",\n	 \"Latitude\":  37.7668,\n	 \"Longitude\": -122.3959,\n	 \"Address\":   \"\",\n	 \"City\":      \"SAN FRANCISCO\",\n	 \"State\":     \"CA\",\n	 \"Zip\":       \"94107\",\n	 \"Country\":   \"US\"\n	 },\n	 {\n	 \"precision\": \"zip\",\n	 \"Latitude\":  37.371991,\n	 \"Longitude\": -122.026020,\n	 \"Address\":   \"\",\n	 \"City\":      \"SUNNYVALE\",\n	 \"State\":     \"CA\",\n	 \"Zip\":       \"94085\",\n	 \"Country\":   \"US\"\n	 }\n	 ]";

int level(char *strjson, int *i, int *depth, int len)
{
	do
	{
		do
		{
			*i++;
			if (*i > len)
			{
				return 0;
			}
		} while (strjson[*i] != '}' && strjson[*i] != ',');
		if (strjson[*i] == ',')
		{
			return 2;
		}
		*depth--;
		if (*i < len && strjson[*i + 1] == ',')
		{
			*i++;
			return 2;
		}
	} while (*depth > 0);
	return 1;
}

int parsejson(char *strjson, int len)
{
	int i = 0, j = 0;
	char decimal = 0;
	int depth = 0, group = 0;
	char temp[20] = {0};
	int retInt = 0;
	float retFloat = 0.0f;
	char retBit = 0;
	if (strjson[i] != '{')
	{
		return 0;
	}
	switch (strjson[i])
	{
	case '{':
	object:
		do
		{
			i++;
			if (i > len)
			{
				return 0;
			}
		} while (strjson[i] <= 32);
		j = 0;
		if (strjson[i] == '\"')
		{
			do
			{
				i++;
				if (i > len)
				{
					return 0;
				}
				temp[j] = strjson[i];
				j++;
			} while (strjson[i] != '\"');
		}
		if (j > 0)
			temp[j - 1] = '\0';
		else
		{
			do
			{
				do
				{
					i++;
					if (i > len)
					{
						return 0;
					}
				} while (strjson[i] != '}' && strjson[i] != ',');
				if (strjson[i] == ',')
				{
					goto object;
				}
				depth--;
				if (i < len && strjson[i + 1] == ',')
				{
					i++;
					goto object;
				}
			} while (depth > 0);
			return 1;
		}

#if MODEL_ENABLED(TEST)
		printf("temp:%s\n", temp);
#endif
		do
		{
			i++;
		} while (strjson[i] <= 32);
		if (strjson[i] == ':')
		{
			do
			{
				i++;
				if (i > len)
				{
					return 0;
				}
			} while (strjson[i] <= 32);
			switch (strjson[i])
			{
			case '\"':
				printf("%s:", temp);
				j = 0;
				do
				{
					i++;
					if (i > len)
					{
						return 0;
					}
					temp[j] = strjson[i];
					j++;
				} while (strjson[i] != '\"');
				if (j >= 1)
					temp[j - 1] = '\0';
				printf("%s\n", temp);
				do
				{
					do
					{
						i++;
						if (i > len)
						{
							return 0;
						}
					} while (strjson[i] != '}' && strjson[i] != ',');
					if (strjson[i] == ',')
					{
						goto object;
					}
					depth--;
					if (i < len && strjson[i + 1] == ',')
					{
						i++;
						goto object;
					}
				} while (depth > 0);
				return 1;
				break;
			case '{':
				depth++;
				goto object;
				break;
			case '[':
				do
				{
					i++;
					if (i > len)
					{
						return 0;
					}
				} while (strjson[i] <= 32);
				switch (strjson[i])
				{
				case '{':
					do
					{
						group = 1;
						j = i;
						do
						{
							do
							{
								i++;
								if (i > len)
								{
									return 0;
								}
								if (strjson[i] == '{')
								{
									group++;
								}
							} while (strjson[i] != '}');
							group--;
						} while (group > 0);
						parsejson(&strjson[j], i - j);
						do
						{
							i++;
							if (i > len)
							{
								return 0;
							}
						} while (strjson[i] <= 32);
						if (strjson[i] == ',')
						{
							i++;
						}
					} while (strjson[i] != ']');
					break;
				case '\"':
					printf("%s:", temp);
					do
					{
						i++;
						if (i > len)
						{
							return 0;
						}
						printf("%c", strjson[i]);
					} while (strjson[i] != ']');
					break;

				default:
					printf("%s:", temp);
					if ((strjson[i] >= 0x30 && strjson[i] <= 0x39) || strjson[i] == '-')
					{
						do
						{
							i++;
							if (i > len)
							{
								return 0;
							}
							printf("%c", strjson[i]);
						} while (strjson[i] != ']');
					}
					break;
				}

				printf("\n");
				do
				{
					do
					{
						i++;
						if (i > len)
						{
							return 0;
						}
					} while (strjson[i] != '}' && strjson[i] != ',');
					if (strjson[i] == ',')
					{
						goto object;
					}
					depth--;
					if (i < len && strjson[i + 1] == ',')
					{
						i++;
						goto object;
					}
				} while (depth > 0);
				return 1;
			case 'T':
			case 't':
				retBit = 1;
				printf("%s %d\n", temp, retBit);

				do
				{
					do
					{
						i++;
						if (i > len)
						{
							return 0;
						}
					} while (strjson[i] != '}' && strjson[i] != ',');
					if (strjson[i] == ',')
					{
						goto object;
					}
					depth--;
					if (i < len && strjson[i + 1] == ',')
					{
						i++;
						goto object;
					}
				} while (depth > 0);
				return 1;
			case 'F':
			case 'f':
				retBit = 0;
				printf("%s %d\n", temp, retBit);

				do
				{
					do
					{
						i++;
						if (i > len)
						{
							return 0;
						}
					} while (strjson[i] != '}' && strjson[i] != ',');
					if (strjson[i] == ',')
					{
						goto object;
					}
					depth--;
					if (i < len && strjson[i + 1] == ',')
					{
						i++;
						goto object;
					}
				} while (depth > 0);
				return 1;
			default:
				if ((strjson[i] >= 0x30 && strjson[i] <= 0x39) || strjson[i] == '-')
				{
					j = i;
					decimal = 0;
					do
					{
						i++;
						if (i > len)
						{
							return 0;
						}
						if (strjson[i] == '.')
						{
							decimal = 1;
						}
					} while (strjson[i] != ',' && strjson[i] != '}');
					if (decimal == 1)
					{
						retFloat = atof(&strjson[j]);
						printf("%s : %.2f\n", temp, retFloat);
					}
					else
					{
						retInt = atoi(&strjson[j]);
						printf("%s : %d\n", temp, retInt);
					}

					do
					{
						do
						{
							i++;
							if (i > len)
							{
								return 0;
							}
						} while (strjson[i] != '}' && strjson[i] != ',');
						if (strjson[i] == ',')
						{
							goto object;
						}
						depth--;
						if (i < len && strjson[i + 1] == ',')
						{
							i++;
							goto object;
						}
					} while (depth > 0);
					return 1;
				}
				break;
			}
		}
		break;
	}
	return 1;
}
int main(int argc, const char *argv[])
{

	int retVal = 0;
	retVal = parsejson(text3, strlen(text3));
	printf("retVal:%d\n", retVal);

	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值