Hello, I'm new to C++.
I'm using Baylor's GNU licensed socket example to pull from omdbapi.com a JSON object with information about movies. This is for a non-academic class and it's a side project just to keep me busy while the class goes over the basics.
I have a std::string JSON and it has the value of:
{"Title":"Star Trek Beyond","Year":"2016","Rated":"PG-13","Released":"22 Jul 2016","Runtime":"122 min","Genre":"Action, Adventure, Sci-Fi","Director":"Justin Lin","Writer":"Simon Pegg, Doug Jung, Gene Roddenberry (based upon \"Star Trek\" created by)","Actors":"Chris Pine, Zachary Quinto, Karl Urban, Zoe Saldana","Plot":"The USS Enterprise crew explores the furthest reaches of uncharted space, where they encounter a new ruthless enemy who puts them and everything the Federation stands for to the test.","Language":"English","Country":"USA, Hong Kong, China","Awards":"Nominated for 1 Oscar. Another 1 win & 17 nominations.","Poster":"https://images-na.ssl-images-amazon.com/images/M/MV5BODgzN2E1YjctODg5Yi00YzYwLWJjZjAtNDg2MGE2Y2MyYjBmXkEyXkFqcGdeQXVyNjM1MTQ0NTQ@._V1_SX300.jpg","Metascore":"68","imdbRating":"7.1","imdbVotes":"154,036","imdbID":"tt2660888","Type":"movie","Response":"True"}
This is my code:
string amazonData = getAmazonData("Star Trek Beyond");
string JSON = isolateJSON(&amazonData);
try {
movieObject = json::parse(JSON);
}
catch (exception& e) {
printf("%s\n", e.what());
}
VS has highlighted the json::parse and said "parse no instance of overloaded function". It appears to accept std::string so I'm not sure what the issue is.
Any help is appreciated.
Does it build even though intellisense is giving you an error? The intellisense compiler is different than the main compiler, so it may just be a problem with the intellisense compiler.
It compiles but it errors. This is the error stack:
Unhandled Exception: System.Runtime.InteropServices.SEHException: External component has thrown an exception.
at _CxxThrowException(Void* , _s__ThrowInfo* )
at nlohmann.detail.from_json
at nlohmann.detail.from_json_fn.call
at nlohmann.detail.from_json_fn.operator()
Do you have an example of the JSON that's failing? Never mind, I see it.
This might be your problem:
"Writer":"Simon Pegg, Doug Jung, Gene Roddenberry (based upon "Star Trek" created by)",
Those quotes around Star Trek should be escaped.
The json I posted appears not to be the raw data, hang on and I'll grab the raw values.
This is the actual data in the JSON string. The value before I was grabbing from VS' visualizer but apparently it doesn't handle it correctly.
{"Title":"Star Trek Beyond","Year":"2016","Rated":"PG-13","Released":"22 Jul 2016","Runtime":"122 min","Genre":"Action, Adventure, Sci-Fi","Director":"Justin Lin","Writer":"Simon Pegg, Doug Jung, Gene Roddenberry (based upon \"Star Trek\" created by)","Actors":"Chris Pine, Zachary Quinto, Karl Urban, Zoe Saldana","Plot":"The USS Enterprise crew explores the furthest reaches of uncharted space, where they encounter a new ruthless enemy who puts them and everything the Federation stands for to the test.","Language":"English","Country":"USA, Hong Kong, China","Awards":"Nominated for 1 Oscar. Another 1 win & 17 nominations.","Poster":"https://images-na.ssl-images-amazon.com/images/M/MV5BODgzN2E1YjctODg5Yi00YzYwLWJjZjAtNDg2MGE2Y2MyYjBmXkEyXkFqcGdeQXVyNjM1MTQ0NTQ@._V1_SX300.jpg","Metascore":"68","imdbRating":"7.1","imdbVotes":"154,036","imdbID":"tt2660888","Type":"movie","Response":"True"}
This still has the same issue. It's invalid JSON.
Hmm, when I pasted it, it had the escape vals.
{"Title":"Star Trek Beyond","Year":"2016","Rated":"PG-13","Released":"22 Jul 2016","Runtime":"122 min","Genre":"Action, Adventure, Sci-Fi","Director":"Justin Lin","Writer":"Simon Pegg, Doug Jung, Gene Roddenberry (based upon \"Star Trek\" created by)","Actors":"Chris Pine, Zachary Quinto, Karl Urban, Zoe Saldana","Plot":"The USS Enterprise crew explores the furthest reaches of uncharted space, where they encounter a new ruthless enemy who puts them and everything the Federation stands for to the test.","Language":"English","Country":"USA, Hong Kong, China","Awards":"Nominated for 1 Oscar. Another 1 win & 17 nominations.","Poster":"https://images-na.ssl-images-amazon.com/images/M/MV5BODgzN2E1YjctODg5Yi00YzYwLWJjZjAtNDg2MGE2Y2MyYjBmXkEyXkFqcGdeQXVyNjM1MTQ0NTQ@._V1_SX300.jpg","Metascore":"68","imdbRating":"7.1","imdbVotes":"154,036","imdbID":"tt2660888","Type":"movie","Response":"True"}
Is that better?
Edit: It appears github was also messing with my escape characters.
Yes, much.
You can add three backticks around your example, like this.
```js
{"foo": "bar"}
```
This is then rendered as
{"foo": "bar"}
Do you know the release number or the commit hash of the version you're using, because it's not the head of master, the line numbers don't line up.
I can't be positive, but I think it's c7afb34e57fc7d343a6c6f3ddee859fe92a7cf92
Unhandled Exception: System.Runtime.InteropServices.SEHException: External component has thrown an exception.
at _CxxThrowException(Void* , _s__ThrowInfo* )
at from_json<basic_json<>,int,0>(basic_json<>* j, Int32* val) in json.hpp:line 817
at from_json_fn.call<basic_json<>,int>(from_json_fn* , basic_json<>* j, Int32* val, priority_tag<1> __unnamed002) in json.hpp:line 856
at from_json_fn.operator()<basic_json<>,int>(from_json_fn* , basic_json<>* j, Int32* val) in json.hpp:line 871
Reformatted, stripped namespaces, template params and paths, to make it easier to read.
Line 817 is:
JSON_THROW(std::domain_error("type must be number, but is " + j.type_name()));
Do you have any more of the call stack? It seems weird to me that this error would come up in parse().
When I get back to the office tomorrow, I'll give the rest of the call stack.
This is the entire stack
Unhandled Exception: System.Runtime.InteropServices.SEHException: External component has thrown an exception.
at _CxxThrowException(Void* , _s__ThrowInfo* )
at nlohmann.detail.from_json<class nlohmann::basic_json<class std::map,class std::vector,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,bool,__int64,unsigned __int64,double,class std::allocator,struct nlohmann::adl_serializer>,int,0>(basic_json<std::map\,std::vector\,std::basic_string<char\,std::char_traits<char>\,std::allocator<char> >\,bool\,__int64\,unsigned __int64\,double\,std::allocator\,nlohmann::adl_serializer>* j, Int32* val) in c:\users\dotlaptop\documents\visual studio 2015\projects\consoleapplication7\consoleapplication7\json.hpp:line 817
at nlohmann.detail.from_json_fn.call<class nlohmann::basic_json<class std::map,class std::vector,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,bool,__int64,unsigned __int64,double,class std::allocator,struct nlohmann::adl_serializer>,int>(from_json_fn* , basic_json<std::map\,std::vector\,std::basic_string<char\,std::char_traits<char>\,std::allocator<char> >\,bool\,__int64\,unsigned __int64\,double\,std::allocator\,nlohmann::adl_serializer>* j, Int32* val, priority_tag<1> __unnamed002) in c:\users\dotlaptop\documents\visual studio 2015\projects\consoleapplication7\consoleapplication7\json.hpp:line 856
at nlohmann.detail.from_json_fn.operator()<class nlohmann::basic_json<class std::map,class std::vector,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,bool,__int64,unsigned __int64,double,class std::allocator,struct nlohmann::adl_serializer>,int>(from_json_fn* , basic_json<std::map\,std::vector\,std::basic_string<char\,std::char_traits<char>\,std::allocator<char> >\,bool\,__int64\,unsigned __int64\,double\,std::allocator\,nlohmann::adl_serializer>* j, Int32* val) in c:\users\dotlaptop\documents\visual studio 2015\projects\consoleapplication7\consoleapplication7\json.hpp:line 871
at nlohmann.adl_serializer<int,void>.from_json<class nlohmann::basic_json<class std::map,class std::vector,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,bool,__int64,unsigned __int64,double,class std::allocator,struct nlohmann::adl_serializer> const &,int>(basic_json<std::map\,std::vector\,std::basic_string<char\,std::char_traits<char>\,std::allocator<char> >\,bool\,__int64\,unsigned __int64\,double\,std::allocator\,nlohmann::adl_serializer>* j, Int32* val) in c:\users\dotlaptop\documents\visual studio 2015\projects\consoleapplication7\consoleapplication7\json.hpp:line 918
at nlohmann.basic_json<std::map,std::vector,std::basic_string<char,std::char_traits<char>,std::allocator<char> >,bool,__int64,unsigned __int64,double,std::allocator,nlohmann::adl_serializer>.get<int,int,0>(basic_json<std::map\,std::vector\,std::basic_string<char\,std::char_traits<char>\,std::allocator<char> >\,bool\,__int64\,unsigned __int64\,double\,std::allocator\,nlohmann::adl_serializer>* ) in c:\users\dotlaptop\documents\visual studio 2015\projects\consoleapplication7\consoleapplication7\json.hpp:line 3193
at nlohmann.basic_json<std::map,std::vector,std::basic_string<char,std::char_traits<char>,std::allocator<char> >,bool,__int64,unsigned __int64,double,std::allocator,nlohmann::adl_serializer>.operator<int,0>(basic_json<std::map\,std::vector\,std::basic_string<char\,std::char_traits<char>\,std::allocator<char> >\,bool\,__int64\,unsigned __int64\,double\,std::allocator\,nlohmann::adl_serializer>* ) in c:\users\dotlaptop\documents\visual studio 2015\projects\consoleapplication7\consoleapplication7\json.hpp:line 3451
at main() in c:\users\dotlaptop\documents\visual studio 2015\projects\consoleapplication7\consoleapplication7\consoleapplication7.cpp:line 54
at _mainCRTStartup()
from_json<basic_json<>,int,0>(basic_json<>* j, Int32* val) in json.hpp:line 817
at from_json_fn.call<basic_json<>,int>(from_json_fn* , basic_json<>* j, Int32* val, priority_tag<1> __unnamed002) in json.hpp:line 856
at from_json_fn.operator()<basic_json<>,int>(from_json_fn* , basic_json<>* j, Int32* val) in json.hpp:line 871
at adl_serializer<int,void>.from_json<basic_json<> const &,int>(basic_json<>* j, Int32* val) in json.hpp:line 918
at basic_json<>.get<int,int,0>(basic_json<>* ) in json.hpp:line 3193
at basic_json<>.operator<int,0>(basic_json<>* ) in json.hpp:line 3451
What is the type of movieObject? This is in operator int(), so it looks like it's the assignment after the json::parse() call.
movieObject is a json object. I believe I tried it with auto, but perhaps not. I'll give that a try after I post this but here is a larger code snippet:
Movie movies[5];
int i;
json movieObject;
loadData(movies);
printf("\n\nMy favorite movies are:\n----------\n\n");
string amazonData = getAmazonData("Star Trek Beyond");
string JSON = isolateJSON(&amazonData);
printf("%s", JSON.c_str());
try {
movieObject = json::parse(JSON);
}
catch (exception& e) {
printf("%s\n", e.what());
}
Edit: I'm unable to get it to work with auto but that may be because I have no idea how to implement the auto class.
auto isn't a class, it means infer the type of the variable from the initializer. Since you don't have an initializer, you can't use auto. You would have to do
try {
auto movieObject = json::parse(JSON);
}
but then you couldn't use movieObject after the try block.
Does the code above include line 54? If so, which line is that?
Huh, exactly like the readme? I think what happened there is that VS was giving me a red squiggly. In my troubleshooting, I must've split that away. But like you said earlier, the compiler may not understand and I should ignore that.
Anyway, now I get "type must be number, but is string"
Edit: And I moved line 54 into the try. It was this printf() that you see.
Movie movies[5];
int i;
loadData(movies);
printf("\n\nMy favorite movies are:\n----------\n\n");
string amazonData = getAmazonData("Star Trek Beyond");
string JSON = isolateJSON(&amazonData);
try {
auto movieObject = json::parse(JSON);
printf("%d) %s.\n\tReleased in %d, received a rating of %.1f and is available on Amazon for $%.2f.\n\n", 1, movieObject["Title"], (int)movieObject["Year"], (double)movieObject["imdbRating"], 9.99);
}
catch (exception& e) {
printf("%s\n", e.what());
}
printf("%d) %s.\n\tReleased in %d, received a rating of %.1f and is available on Amazon for $%.2f.\n\n", 1, movieObject["Title"], (int)movieObject["Year"], (double)movieObject["imdbRating"], 9.99);
movieObject["Year"] and movieObject["imdbRating"] are both strings: "Year":"2016" "imdbRating":"7.1"
string title = movieObject["Title"];
string year = movieObject["Year"];
string rating = movieObject["imdbRating"];
printf("%d) %s.\n\tReleased in %s, received a rating of %s and is available on Amazon for $%.2f.\n\n", 1, title.c_str(), year.c_str(), rating.c_str(), 9.99);
gregmarr: Thank you so much, you've taught me a lot. We're not this far in the class yet, so this has been a great chance to learn. Thanks nlohmann for the library as well.
Good observation, @gregmarr.
Thanks @gregmarr for the support!
Most helpful comment
movieObject["Year"]andmovieObject["imdbRating"]are both strings:"Year":"2016""imdbRating":"7.1"