I am trying read a text file which has Valid JSON content but not string. The below code works fine if it is a string dump. For example - if file contents are like this "{ \"happy\": true, \"pi\": 3.141 }" then it will parse without errors. Now I want to find out a way which minimizes these conversion ? How to convert JSON content to String dump in C++ using any standard lib? I am using nlohmann for now, but seems like this requires additional coding. Please educate me if I can hack this with simple code.
My Code
#include <iostream>
#include <fstream>
#include <streambuf>
#include <nlohmann/json.hpp>
using namespace std;
using json = nlohmann::json;
int main()
{
std::fstream f_json("C://json.txt");
json jFile;
try {
jFile = json::parse(f_json);
}
catch (json::parse_error &e)
{
std::cerr << e.what() << std::endl;
}
return 0;
}
Our client produces JSON files which is like below.
{
"happy": true,
"pi": 3.141
}
My file is under C:/test.json, so it dint had the permission to open it. Now I placed it in proper folder. Now its working fine.
I like to use ThorsSerializer. Disclaimer I wrote it.
#include "ThorSerialize/JsonThor.h"
#include "ThorSerialize/SerUtil.h"
#include <sstream>
#include <iostream>
#include <string>
struct MyObj
{
bool happy;
double pi;
};
ThorsAnvil_MakeTrait(MyObj, happy, pi);
Example Usage:
int main()
{
using ThorsAnvil::Serialize::jsonImport;
using ThorsAnvil::Serialize::jsonExport;
std::stringstream file(R"({ "happy": true, "pi": 3.141 })");
MyObj data;
file >> jsonImport(data);
std::cout << jsonExport(data) << "\n";
}
Output:
{
"happy": true,
"pi": 3.141
}
It works the same for a file stream. But you should not escape the " characters in the file.
Related
I am trying to access an JSON array using 'nlohmann' library, as the example below shows:
#include <iostream>
#include <string>
#include "json.hpp"
using json = nlohmann::json;
int main() {
{
const std::string str(
R"(
{
"result":{
"lines":[
{
"i":1,
"w":7,
},
{
"i":1,
"w":8,
}
]
},
"success":true
}
)");
json root(str);
auto result = root.find("result");
if (result != root.end()) {
std::cout << *result << std::endl;
} else {
std::cout << "'result' not found\n";
}
}
}
Can anyone help and explain why the output is 'result' not found? According to the examples I read in https://github.com/nlohmann/json and other references I found, it should work.
I found the error.
I should be json root(json::parse(str)); and not json root(str);
i have made a example for try the JsonCpp library.
I have included it in my project, the project content is this:
#include <cstdlib>
#include <string>
#include <fstream>
#include <iostream>
#include <json\value.h>
#include <json\json.h>
using namespace std;
int main()
{
Json::Reader reader; //for reading the data
Json::Value newValue; //for modifying and storing new values
Json::StyledStreamWriter writer; //for writing in json files
//opening file using fstream
ifstream file("items.json");
// check if there is any error is getting data from the json file
if (!reader.parse(file, newValue)) {
cout << reader.getFormattedErrorMessages();
exit(1);
}
cout << newValue["Category"] << endl;
file.close();
system("pause");
}
The json file name is items.json and its content is this:
{
"Category" : "Technical",
"Date" : "1 January 2021",
"Name" : "Java2Blog",
"first" : "Shishank",
"last" : "Jain"
}
But when i compile and run the project, it generate this error:
* Line 1, Column 1
Syntax error: value, object or array expected.
I have followed this guide: https://java2blog.com/json-parser-cpp/
this is my first time using json in a C ++ project
I have solved my problem.
The json file was already encoded in UTF-8, and the file path was correct.
I have changed my code like this:
#include <fstream>
#include <iostream>
#include <json\json.h>
using namespace std;
int main()
{
ifstream file;
file.open("items.json");
if (!file)
{
cout << "File non esiste" << endl;
}
else
{
Json::Reader reader; //for reading the data
Json::Value value; //for modifying and storing new values
reader.parse(file, value);
cout << value["Category"] << endl;
}
file.close();
system("pause");
}
I apologize to everyone for the inconvenience
Actually I am trying to parse a json file using rapidjson library . But when i am trying to add this header file in my code it shows me an error like this
"[Error] rapidjson/document.h: No such file or directory" and
"recipe for target 'main_1.o' failed"
here main_1 is my file name.
This is my actual code
#include<stdio.h>
#include "rapidjson/document.h"
using namespace rapidjson;
Document document;
document.Parse(json);
int main()
{
char name[50];
int t_value;
return 0;
}
And also i haven't idea about where i want to add my json file?
But i really don't know where i did a mistake? please anyone help me.
Kindly check the below link for installation of json, you can also visit rapidjson official website
RapidJson installation
And for your code:
Download all header files of rapidjson and keep it inside your current folder under rapidjson folder(new folder)
Write the below code inside main, compiler error will occur due to this.
Document document;
document.Parse(json);
If you are using Ubuntu then package manager can be used to install the rapidjson lib
$ sudo apt-get update
$ sudo apt-get install rapidjson-dev
The path of the rapidjson include for me was
/usr/include/rapidjson
and in the cpp/hpp file
#include <rapidjson/document.h>
worked for me
sample program to load file
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <rapidjson/document.h>
#include <rapidjson/istreamwrapper.h>
#include <rapidjson/writer.h>
#include <rapidjson/stringbuffer.h>
#include <rapidjson/ostreamwrapper.h>
int main()
{
using namespace rapidjson;
std::ifstream ifs { R"(myfile.json)" };
if ( !ifs.is_open() )
{
std::cerr << "Could not open file for reading!\n";
return EXIT_FAILURE;
}
IStreamWrapper isw { ifs };
Document doc {};
doc.ParseStream( isw );
StringBuffer buffer {};
Writer<StringBuffer> writer { buffer };
doc.Accept( writer );
if ( doc.HasParseError() )
{
std::cout << "Error : " << doc.GetParseError() << '\n'
<< "Offset : " << doc.GetErrorOffset() << '\n';
return EXIT_FAILURE;
}
const std::string jsonStr { buffer.GetString() };
std::cout << jsonStr << '\n';
std::cout <<"done\n";
return EXIT_SUCCESS;
}
Demo code Source:
How to read json file using rapidjson and output to std::string?
I got the following code from internet. I expect it to print contents of post request of any URL.It is printing ->Added new Id: {"listOfAssets":[{"assetName":"Gold Asset"}]}->which is correct.I guess this is a string output. I want output in json which I need to convert to C++(serialize) Can someone advice what more should I do?I am running the code in linux environment.1st let me know how to get json output.serializing can be done later. To do this I added 2lines
It is giving me errors
terminate called after throwing an instance of 'web::http::http_exception'
what(): Incorrect Content-Type: must be textual to extract_string, JSON to extract_json.
#include <cpprest/http_client.h>
#include <pplx/pplxtasks.h>
#include <cpprest/json.h>
#include <stdlib.h>
#include <iostream>
#include <vector>
#include <cpprest/details/http_constants.dat>
#include <cpprest/http_msg.h>
using namespace std;
using namespace web;
using namespace web::json;
using namespace pplx;
using namespace web::http;
using namespace web::http::client;
using namespace web::http::details;
pplx::task<int> Post()
{
return pplx::create_task([]
{
json::value postData;
postData["name"] = json::value::string("Joe Smith");
postData["sport"] = json::value::string("Baseball");
http_client client("http://54.191.233.99:8080/sparkAPIs/testing.html");
return client.request(methods::POST, "",
/*postData.serialize().c_str(),*/ "application/json");
}).then([](http_response response)
{
if(response.status_code() == status_codes::OK)
{
//auto body = response.extract_string();
//std::cout << "Added new Id: " << body.get().c_str() << std::endl;
auto body = response.extract_json();
body.get();
//return std::stoi(body.get().c_str());
}
return 0;
});
}
int main()
{
cout<<"hello world"<<endl;
Post().wait();
}
Basically I need to open and read a list of files I get from another command.
For each line of output of popen
open a file usen ifstream.open
it compiles and if I put the file name directly it works fine, but it doesn't do anything when using popen output. I've seen questions like this but none of this particular way of giving filenames.
here's the code:
#include <iostream>
#include <sqlite3.h>
#include <stdio.h>
#include <fstream>
using namespace std;
int main () {
ifstream singlefile;
FILE *filelist;
char filename[512];
string progline;
if(!(filelist = popen("find `pwd` -name \"*.js\"", "r"))){
return 1;
}
while( fgets(filename, sizeof(filename), filelist)!=NULL)
{
cout << filename;
singlefile.open(filename, ifstream::in);
while ( singlefile.good() )
{
getline (singlefile,progline);
cout << progline << endl;
}
singlefile.close();
}
pclose(filelist);
return 0;
}
next step would be not open each file inside the loop but to store the file list and then open each file.
Thanks
fgets keeps the trailing newline, resulting in a filename of a non-existing file. Also the stream state is only updated after reading. If I replace the while body with the following code, it works for me:
cout << filename;
size_t len = strlen(filename);
// chop off trailing newline
if (len > 1 && filename[len - 1] == '\n') filename[len - 1] = 0;
singlefile.open(filename, ifstream::in);
while ( getline(singlefile, progline) )
{
cout << progline << endl;
}
singlefile.close();
If you actually want to iterate through a list of files, I'd use Boost.Filesystem, which has a nice C++ interface, works for all filenames (even for those with newlines), and is platform-independent.
If this actually is only an example and your actual command is not find, there is still some room for simplification. Here is a suggestion that uses Boost.Iostreams to get rid of most of the C function calls (it would be great to have a device source reading from a process's standard output, but Boost.Iostreams lacks that):
#include <cstdio>
#include <iostream>
#include <fstream>
#include <stdexcept>
#include <string>
#include <stdio.h>
#include <boost/noncopyable.hpp>
#include <boost/iostreams/stream.hpp>
#include <boost/iostreams/device/file_descriptor.hpp>
using namespace std;
namespace io = boost::iostreams;
class Popen: private boost::noncopyable {
public:
explicit Popen(const char* command):
m_stream(popen(command, "r")) {
if (!m_stream) throw runtime_error("popen failed");
}
~Popen() {
pclose(m_stream);
}
FILE* stream() const {
return m_stream;
}
private:
FILE* m_stream;
};
int main() {
Popen pipe_wrapper("find `pwd` -name \"*.cpp\"");
io::file_descriptor_source pipe_device(fileno(pipe_wrapper.stream()), io::never_close_handle);
io::stream<io::file_descriptor_source> pipe_stream(pipe_device, 0x1000, 0x1000);
string filename;
while (getline(pipe_stream, filename)) {
cout << filename << endl;
ifstream file_stream(filename.c_str(), ifstream::in);
string progline;
while (getline(file_stream, progline)) {
cout << progline << endl;
}
}
}