说明
这个是基于我的使用需求,所以在打印输出信息上面有些删减。解析是完整的,可以根据你的需求自己打印。
没有使用堆,没有树,使用了递归(解析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;
}