Search code examples
c++jsonjsoncpp

Writing lines of file into JSON using C++ and jsoncpp


I have a text file that I'm trying to convert to a JSON object using jsoncpp in my c++ application.

The contents of the file is formatted as so:

system type : Atheros AR7241 rev 1
machine     : Ubiquiti UniFi
processor   : 0
cpu model   : MIPS 24Kc V7.4
BogoMIPS    : 259.27

Which seems pretty handy to start. I needed to keys to match the first column and the values the second column, as so:

{ "meh" : [{ "system type" : "Atheros AR7241 rev 1", "machine" : "Ubiquiti UniFi" ...

I can write the file in it's entriety to a json object. But that's as far as I can get...

Json::Value root;
string line;

ifstream myfile( "/proc/cpuinfo" );
if (myfile)
{
    while (getline( myfile, line ))
    {
        root["test"] = line;
        cout << root;
    }
    myfile.close();
}

Which is close but obviously gives me json like so:

{
    "test" : "system type   : Atheros AR7241 rev 1"
}

Am new to c++ I don't know how to split the lines at the colon and use the first half for the key instead of "test".. Can someone suggest a way to go about this?


Solution

  • I would suggest using a combination of "string::find()" and "string::substr()".

    Or some regular expression stuff but i think that would need to go over the standard library.

    Example:

    std::string::size_type n;
    std::string key;
    std::string value;
    
    n = line.find(':');
    
    key = line.substr( 0, n );
    value = line.substr( n+1 );
    

    Then would need maybe to strip the key and values from white characters. I won't cover it since there are few question and answers on SO how to do it. E.g:

    1. Similar function in C++ to Python's strip()?
    2. What's the best way to trim std::string?

    EDIT:

    Complete example code split.cpp:

    /// TRIMMING STUFF
    // taken from https://stackoverflow.com/a/217605/1133179
    #include <algorithm> 
    #include <functional> 
    #include <cctype>
    #include <locale>
    
    // trim from start
    static inline std::string &ltrim(std::string &s) {
            s.erase(s.begin(), std::find_if(s.begin(), s.end(), std::not1(std::ptr_fun<int, int>(std::isspace))));
            return s;
    }
    
    // trim from end
    static inline std::string &rtrim(std::string &s) {
            s.erase(std::find_if(s.rbegin(), s.rend(), std::not1(std::ptr_fun<int, int>(std::isspace))).base(), s.end());
            return s;
    }
    
    // trim from both ends
    static inline std::string &trim(std::string &s) { return ltrim(rtrim(s)); }
    /// ~~~ TRIMMING STUFF ~~~
    
    
    #include <string>
    #include <iostream>
    
    int main(){
    std::string::size_type n;
    std::string key;
    std::string value;
    
    std::string line = "system type : Atheros AR7241 rev 1";
    
    n = line.find(':');
    
    key = line.substr( 0, n );
    value = line.substr( n+1 );
    std::cout << "line: `" << line << "`.\n";
    std::cout << "key: `" << key << "`.\n";
    std::cout << "value: `" << value << "`.\n";
    
    
    ///  With trimming
    
    std::cout << "{\n "json" : [{ \"" << trim(key) << "\" : \"" << trim(value) << "\" }]\n}\n";
    }
    

    Execute:

    luk32:~/projects/tests$ g++ ./split.cpp
    luk32:~/projects/tests$ ./a.out 
    line: `system type : Atheros AR7241 rev 1`.
    key: `system type `.
    value: ` Atheros AR7241 rev 1`.
    {
     "json" : [{ "system type" : "Atheros AR7241 rev 1" }]
    }
    

    I think it's ok.