[C++][原创]jsoncpp用法及其注意事项
发现jsoncpp用的人很多,但是实际用起来问题很多。
第一个典型的问题,怎么判断一个字符串是不是json格式,因为开发中是2种编程语言的开发者通过json协议,避免不了有时候把json格式弄错了,但是好像Jsoncpp没有这个功能,我尝试把字符串类似下面
std::string data = "123";
Json::Reader reader;
Json::Value root;
if (!reader.parse(data, root))
{
cerr << "parse failed \n";
return 0;
}
结果解析是不报错的,但是这个明显就不是json字符串,咋办,只能写个函数了,在网上找了个效果不错
bool IsJsonIllegal(const char *jsoncontent)
{
std::stack<char> jsonstr;
const char *p = jsoncontent;
char startChar = jsoncontent[0];
char endChar = '\0';
bool isObject = false;//防止 {}{}的判断
bool isArray = false;//防止[][]的判断
while (*p != '\0')
{
endChar = *p;
switch (*p)
{
case '{':
if (!isObject)
{
isObject = true;
}
else if (jsonstr.empty())//对象重复入栈
{
return false;
}
jsonstr.push('{');
break;
case '"':
if (jsonstr.empty() || jsonstr.top() != '"')
{
jsonstr.push(*p);
}
else
{
jsonstr.pop();
}
break;
case '[':
if (!isArray)
{
isArray = true;
}
else if (jsonstr.empty()){
return false;
}
jsonstr.push('[');
break;
case ']':
if (jsonstr.empty() || jsonstr.top() != '[')
{
return false;
}
else
{
jsonstr.pop();
}
break;
case '}':
if (jsonstr.empty() || jsonstr.top() != '{')
{
return false;
}
else
{
jsonstr.pop();
}
break;
case '\\'://被转义的字符,跳过
p++;
break;
default:
;
}
p++;
}
if (jsonstr.empty())
{
//确保是对象或者是数组,之外的都不算有效
switch (startChar)//确保首尾符号对应
{
case '{':
{
if (endChar = '}')
{
return true;
}
return false;
}
case '[':
{
if (endChar = ']')
{
return true;
}
return false;
}
default:
return false;
}
return true;
}
else
{
return false;
}
}
第二个问题:我们经常需要判断是不是存在某个key,比如json字符串{"name":"Alice"},判断里面有没有Age这个key,经过测试发现以下方法可以
std::string data = "{\"name\":\"Alice\"}";
Json::Reader reader;
Json::Value root;
if (!reader.parse(data, root))
{
cerr << "parse failed \n";
return 0;
}
//第一种
if(root["Age"].isString())//这个可以
{
std::string age=root["Age"].asString();
}
//第二种
if(root["Age"].isNull())//这个可以
{
}
//第三种
std::string age=root["Age"].asString();//直接硬来其实也是可以只不过是空的
//第四种
if(root.isMember("Age"))
{
std::cout<<"has type data"<<std::endl;
}else
{
std::cout<<"no type data"<<std::endl;
}
注意上面可以是建立在它是个json字符串基础上,如果字符串是123就报错了
第三个问题:我们用jsoncpp当然是取里面键值对中的值。一般首选判断其类型,然后转换即可,类型判断有
bool isNull() const;
bool isBool() const;
bool isInt() const;
bool isInt64() const;
bool isUInt() const;
bool isUInt64() const;
bool isIntegral() const;
bool isDouble() const;
bool isNumeric() const;
bool isString() const;
bool isArray() const;
bool isObject() const;
转换的时候把is改成as就行,比如
std::string age = root["Age"].asString();
注意root["Age"].asString()本身不是std::string类型而是Json::String,这个是默认强制转换。
关于jsoncpp用法还有很多,比如如何从流读取,从文件读取,从字符串解析等等。由于这些网上都有不再赘述,这里只介绍常见的问题