JSON文件是指那些以".json"为后缀的,这些文件内容有一些共同的特点。
1.关键字以英文的引号为标记如, " xxxx"的xxxx就是一个关键字
2.关键字面一定会跟英文的冒号:和大括号 {
3.参数一般的形式为 "参数名" :"字符参数","参数名":数值,这两种
一定后面存在中括号 [
5.结尾一定能找到对应的括号。
那么剩下的就简单了,如何根据以上特征,去解读json文件呢?
为了加深印象这里只贴一些关键函数的代码(PS:断断续续写了三天勉强能用)
第一步首先是头文件
enum KEY//这个是关键字的一些操作
{
QUOTATION=0,
COLON=1,
LEFT_BRACKET,
RIGHT_BRACKET,
LEFT_BRACES,
RIGHT_BRACES,
POINT
};
typedef struct _JsonKey
{
string BaseName;
string KeyName;
int BeginLineNo;
int EndLineNo;
}JsonKey;
public:
BOOL ReadJsonFile(string filepath);//加载json文件
int GetKeyWordPos(KEY key,string LineWord,int SrcLen);//输入的是substr
int GetKeyWordPos(KEY key, string LineWord);//输入的是原字符
private:
//1.第一次解析分析,关键字,数组,值等等
BOOL GetKeyWord(map<int, string> &bKeyMap, map<string, int>&ParaKeyMap, map<int, string>&ParaValueMap, map<int, string>&ListMap);
//2.第二次分析,构造JsonKey
BOOL GetKeyWord2();
protected:
vector<string> m_nData;//总的数据
map<int, string> m_nKeyMap;//关键字,行
map<string, int> m_nParaKeyMap;//参数名,行
map<int, string> m_ParaValueMap;//参数值,行
map<int, string> m_nListMap;//list
JsonKey *m_nJsonKey;
protected:
int m_nLineCount;//行数
第二步,具体实现
//ReadJsonFile
BOOL CJsonOperate::ReadJsonFile(string filepath)
{
//后缀判断
int p = GetKeyWordPos(KEY::POINT, filepath);
if (p<0)
{
AfxMessageBox("The path is Error!!!");
return FALSE;
}
else
{
int n = () - 1 - p;
string bStr = (p + 1, n);
if (bStr!="json")
{
AfxMessageBox("The File is is not JSON file!!!");
return FALSE;
}
}
char *pPath = new char[()+1];//+1:防止越界
memset(pPath, NULL, sizeof(char)*());
strcpy(pPath, filepath.c_str());//转换一下
ifstream Cfile(pPath);
if (!Cfile.is_open())
{
AfxMessageBox("Error: Open file failed!!!");
delete[] pPath;
return FALSE;
}
else
{
m_nData.clear();
}
string data;
while (getline(Cfile, data))
{
m_nData.push_back(data);//先把说有的数据读出来
}
m_nLineCount = m_nData.size();
if (m_nLineCount<1)
{
AfxMessageBox("Error: The File is NULL!!!");
return FALSE;
}
();
GetKeyWord(m_nKeyMap, m_nParaKeyMap, m_ParaValueMap,m_nListMap);
GetKeyWord2();
delete[] pPath;
return TRUE;
}
BOOL CJsonOperate::GetKeyWord(map<int, string>&bKeyMap, map<string, int>&ParaMap, map<int, string>&ParaValueMap,map<int, string>&ListMap)
{
//substr(起始位,位数)
bool test = true;
();
();
();
();
int nPos = 0;
if (m_nData.size()==0)
{
AfxMessageBox("Error:data is NULL");
}
for (int i = 0; i < m_nLineCount;i++)
{
//找左边引号
if (test)
{
string data = m_nData.at(i);
}
int pos = GetKeyWordPos(KEY::QUOTATION, m_nData.at(i),m_nData.at(i).length());
if (pos<0)
{
continue;
}
//找右边引号
if (test)
{
string data = m_nData.at(i).substr(pos + 1, m_nData.at(i).size() - pos);
}
int pos1 = GetKeyWordPos(KEY::QUOTATION, m_nData.at(i).substr(pos + 1, m_nData.at(i).size() - pos), m_nData.at(i).length());
if (pos1<0)
{
continue;
}
//已经找到Key
//
//分析key的周围先找冒号
if (test)
{
string data = m_nData.at(i).substr(pos1 + 1, m_nData.at(i).size() - pos1);
}
int pos2 = GetKeyWordPos(KEY::COLON, m_nData.at(i).substr(pos1 + 1, m_nData.at(i).size() - pos1), m_nData.at(i).length());
if (pos2>=0)
{
//说明是有,再找{
if (test)
{
string data = m_nData.at(i).substr(pos2 + 1, m_nData.at(i).size() - pos2);
}
int pos3 = GetKeyWordPos(KEY::LEFT_BRACES, m_nData.at(i).substr(pos2 + 1, m_nData.at(i).size() - pos2), m_nData.at(i).length());
if (pos3>=0)
{
//key
(pair<int, string>(i, m_nData.at(i).substr(pos + 1, pos1-pos-1)));
//在这里还需要一个反馈验证,用于验证分组
}
else
{
//没有,先判断是来到List还是Para,有[代表是list,没有代表参数区
int pos6 = GetKeyWordPos(KEY::LEFT_BRACKET, m_nData.at(i).substr(pos2 + 1, m_nData.at(i).size() -pos2), m_nData.at(i).length());
if (pos6>0)
{
//list
(pair<int, string>(i, m_nData.at(i).substr(pos + 1, pos1-pos-1)));
}
else
{
(pair<string, int>(m_nData.at(i).substr(pos + 1, pos1-pos-1), i));
//再去找参数
string bbb = m_nData.at(i).substr(pos2 + 1, m_nData.at(i).size() - 1);
int pos4 = GetKeyWordPos(KEY::QUOTATION, m_nData.at(i).substr(pos2 + 1, m_nData.at(i).size() - pos2), m_nData.at(i).length());
if (pos4 >= 0)//从string和数值
{
bbb = m_nData.at(i).substr(pos4 + 1, m_nData.at(i).size() - pos4);
int pos5 = GetKeyWordPos(KEY::QUOTATION, m_nData.at(i).substr(pos4+1, m_nData.at(i).size() - pos4), m_nData.at(i).length());
//paravalue
(pair<int, string>(i, m_nData.at(i).substr(pos4+1, pos5-pos4-1)));
}
else
{
nPos = pos2;
int n = m_nData.at(i).size() - 1 - (nPos + 1);
(pair<int, string>(i, m_nData.at(i).substr(nPos + 1, n)));
}
}
}
}
}
if (() == 0 || () == 0 || () == 0 || () == 0)
{
AfxMessageBox("Error: No KeyWord");
();
();
();
();
return FALSE;
}
return TRUE;
}
int CJsonOperate::GetKeyWordPos(KEY key, string LineWord,int StrLen)
{
char bKey;
int pos = -1;
if (key == KEY::QUOTATION)
{
bKey = '\"';
}else if (key == KEY::COLON)
{
bKey = ':';
}
else if (key == KEY::LEFT_BRACKET)
{
bKey = '[';
}
else if (key == KEY::RIGHT_BRACKET)
{
bKey = ']';
}else if (key==KEY::POINT)
{
bKey = '.';
}
else if (key==KEY::LEFT_BRACES)
{
bKey = '{';
}
else if (key == KEY::RIGHT_BRACES)
{
bKey = '}';
}
size_t p = (bKey);
pos = static_cast<int>(p);
if (()<StrLen)
{
if (pos>-1)
{
pos += (StrLen - ());
}
}
return pos;
}
int CJsonOperate::GetKeyWordPos(KEY key, string LineWord)
{
char bKey;
int pos = -1;
if (key == KEY::QUOTATION)
{
bKey = '\"';
}
else if (key == KEY::COLON)
{
bKey = ':';
}
else if (key == KEY::LEFT_BRACKET)
{
bKey = '[';
}
else if (key == KEY::RIGHT_BRACKET)
{
bKey = ']';
}
else if (key == KEY::POINT)
{
bKey = '.';
}
else if (key == KEY::LEFT_BRACES)
{
bKey = '{';
}
else if (key == KEY::RIGHT_BRACES)
{
bKey = '}';
}
size_t p = (bKey);
pos = static_cast<int>(p);
return pos;
}
最后,GetKeyWord2()这个是核心问题,应该怎么实现呢,下面给出部分代码
BOOL CJsonOperate::GetKeyWord2()
{
if (m_nKeyMap.size() == 0)
{
AfxMessageBox("Error: No KeyWord");
m_nKeyMap.clear();
return FALSE;
}
//1.创建数组,赋值
int n = 0;
int nKeyNum = m_nKeyMap.size();
m_nJsonKey = new JsonKey[nKeyNum];
map<int, string>::iterator iter;
for (int i = 0; i < m_nLineCount;i++)
{
iter = m_nKeyMap.find(i);
if (iter != m_nKeyMap.end())
{
m_nJsonKey[n].BaseName = "";
m_nJsonKey[n].KeyName = iter->second;
m_nJsonKey[n].BeginLineNo = i;
m_nJsonKey[n].EndLineNo = 0;
n++;
}
}
//2.对数组进行求解,还是把源码放上去吧
string bBase;
for (int j = 0; j < nKeyNum;j++)
{
int Left_Num = 1;
int Right_Num = 0;
string bStr;
for (int i = 0; i < m_nLineCount - m_nJsonKey[j].BeginLineNo;i++)
{
int p = GetKeyWordPos(KEY::RIGHT_BRACES, m_nData.at(m_nJsonKey[j].BeginLineNo + 1+i));
if (p > -1)
{
Right_Num++;
}
else
{
int p = GetKeyWordPos(KEY::LEFT_BRACES, m_nData.at(m_nJsonKey[j].BeginLineNo + 1 + i));
if (p > -1)
{
Left_Num++;
}
}
if (Left_Num == Right_Num)
{
m_nJsonKey[j].EndLineNo = m_nJsonKey[j].BeginLineNo + 1 + i;
if (j>0)
{
//找他上面endlineno最大的
int Max=j;
for (int z = j; z > 0;z--)
{
if (m_nJsonKey[j].EndLineNo<m_nJsonKey[z-1].EndLineNo)
{
Max = z - 1;
}
}
m_nJsonKey[j].BaseName = m_nJsonKey[Max].KeyName;
}
else
{
m_nJsonKey[j].BaseName = m_nJsonKey[j].KeyName;
}
break;
}
}
}
}
有大神有更好的办法的话请指正谢谢!