I wrote a very simple JSON parser in C++ a while ago. It’s just a pair of header and source files, thus very easy to use (compile the .cc file and link with your source). Check it out here.
Here are a few examples:
string teststr(
"{"
" \"foo\" : 1,"
" \"bar\" : false,"
" \"person\" : {\"name\" : \"GWB\", \"age\" : 60},"
" \"data\": [\"abcd\", 42]"
"}"
);
istringstream input(teststr);
Object o;
assert(o.parse(input));
assert(1 == o.get<long>("foo"));
assert(o.has<bool>("bar"));
assert(o.has<Object>("person"));
assert(o.get<Object>("person").has<long>("age"));
assert(o.has<Array>("data"));
assert(o.get<Array>("data").get<long>(1) == 42);
assert(o.get<Array>("data").get<string>(0) == "abcd");
assert(!o.has<long>("data"));
Caveat: It currently does not support floating-point numbers.
Comments 4
Hrm, someone who’s less lazy than me should just add support for that; floating point numbers are just regex in complexity. You could detect /that/ it’s floating point by whether it has any ‘.’ in it (after you know it’s not a string). I’d do it but, I’m lazy. Oh ^%Q@#$ maybe I will.
Posted 09 Mar 2009 at 11:38 am ¶Bill A Bong: The project I used it in did not need floating point numbers, so I lacked the motivation to write more code.
I wrote the code so that it doesn’t depend on anything other than the standard library. If you want to keep it that way, you cannot use regular expression.
Posted 09 Mar 2009 at 5:34 pm ¶Thanks for creating this, here are some methods for detecting floating point and exponents, a little closer to the standard:
bool rewind_input(std::istream& input, std::string &str) { for (int i=str.size()-1;i>=0;i–) { input.putback(str[i]); } }
char push_digits(std::istream& input, std::string &str) { char ch=0; if (match(“-”, input)) str.push_back(‘-’); else match(“+”, input); while(input && !input.eof()) { input.get(ch); if (!isdigit(ch)) { input.putback(ch); return ch; } if (!input.fail()) { str.push_back(ch); } } return 0; }
bool parse_number(std::istream& input, long* value) { eat_whitespaces(input); char ch=0; std::string value_str; ch=push_digits(input,value_str); if (ch==’.') { rewind_input(input,value_str); value_str.clear(); } else if (ch==’e’ or ch==’E') { value_str.push_back(input.get()); push_digits(input,value_str); } if (value_str.size() > 0) { std::istringstream(value_str) >> *value; return true; } else { return false; } }
bool parse_number(std::istream& input, double* value) { eat_whitespaces(input); char ch=0; std::string value_str; ch=push_digits(input,value_str); value_str.push_back(input.get()); char next = input.peek(); if (ch==’.’ and isdigit(next)) { ch=push_digits(input,value_str); if (ch==’e’ or ch==’E') { value_str.push_back(input.get()); push_digits(input,value_str); } } else { rewind_input(input,value_str); value_str.clear(); } if (value_str.size() > 0) { std::istringstream(value_str) >> *value; return true; } else { return false; } }
Posted 28 Oct 2009 at 11:09 am ¶Very nice code. There is a problem though with your parser in that the entire thing could be just an array.
I’m not sure how to parse this valid json with your code.
example: string teststr(“[ \"test\",30,\"er\" ]” ) ;
Posted 06 Jan 2010 at 2:30 pm ¶Post a Comment