5

json ライブラリを使用して文字列をシリアル化/逆シリアル化せずに、json 形式で webservice を呼び出すアプリケーションを vc++ で作成しています。手動で作成して json 文字列を送信しています。 C++ のライブラリ

応答

{ 
    "Result": "1",
    "gs":"0",
    "ga":"0",
    "la":"0",
    "lb":"0",
    "lc":"0",
    "ld":"0",
    "ex":"0",
    "gd":"0"        
}
4

2 に答える 2

2

これは、stl を使用して応答文字列を解析する大まかな実装にすぎませんが、それをさらに処理するための開始点として使用できます。任意の正規表現 (例: boost::regex ) を使用できる場合、この解析はより簡単に実行できますが、おそらく特定の json パーサーを使用することもできるため、これについては忘れてください ;)

#include <iostream>
#include <sstream>
#include <string>

const char* response = "\
\
{\
    \"Result\": \"1\",\
    \"gs\":\"0\",\
    \"ga\":\"0\",\
    \"la\":\"0\",\
    \"lb\":\"0\",\
    \"lc\":\"0\",\
    \"ld\":\"0\",\
    \"ex\":\"0\",\
    \"gd\":\"0\"\
}";

int main(int argc, char* argv[])
{
    std::stringstream ss(response); //simulating an response stream
    const unsigned int BUFFERSIZE = 256;

    //temporary buffer
    char buffer[BUFFERSIZE];
    memset(buffer, 0, BUFFERSIZE * sizeof(char));

    //returnValue.first holds the variables name
    //returnValue.second holds the variables value
    std::pair<std::string, std::string> returnValue;

    //read until the opening bracket appears
    while(ss.peek() != '{')         
    {
        //ignore the { sign and go to next position
        ss.ignore();
    }

    //get response values until the closing bracket appears
    while(ss.peek() != '}')
    {
        //read until a opening variable quote sign appears
        ss.get(buffer, BUFFERSIZE, '\"'); 
        //and ignore it (go to next position in stream)
        ss.ignore();

        //read variable token excluding the closing variable quote sign
        ss.get(buffer, BUFFERSIZE, '\"');
        //and ignore it (go to next position in stream)
        ss.ignore();
        //store the variable name
        returnValue.first = buffer;

        //read until opening value quote appears(skips the : sign)
        ss.get(buffer, BUFFERSIZE, '\"');
        //and ignore it (go to next position in stream)
        ss.ignore();

        //read value token excluding the closing value quote sign
        ss.get(buffer, BUFFERSIZE, '\"');
        //and ignore it (go to next position in stream)
        ss.ignore();
        //store the variable name
        returnValue.second = buffer;

        //do something with those extracted values
        std::cout << "Read " << returnValue.first<< " = " << returnValue.second<< std::endl;
    }
}
于 2012-04-24T11:38:05.697 に答える
1

このような目的でboost::spirit::qiを使用する方法の小さな例を次に示します。

Boostは確かにサードパーティのライブラリであることに注意してください!

JSONファイルを受け取り、次の内容でjson-example.txtに保存したと仮定します。

{{
    "結果": "1"、
    "gs": "0"、
    "ga": "0"、
    "la": "0"、
    "lb": "0"、
    "lc": "0"、
    "ld": "0"、
    "ex": "0"、
    "gd": "0"
}

ここで、 key:file方式ですべてのアイテムを受け取りたいと仮定します。これを行う方法は次のとおりです。

#include <vector>
#include <string>
#include <fstream>
#include <map>
#include <boost/spirit/include/qi.hpp>
#include <boost/fusion/adapted/std_pair.hpp>

namespace qi = boost::spirit::qi;

template<typename Iterator>
struct jsonparser : qi::grammar<Iterator, std::map<std::string, int>()>
{
    jsonparser() : jsonparser::base_type(query, "JSON-parser")
    {
        using qi::char_;
        using qi::int_;
        using qi::blank;
        using qi::eol;
        using qi::omit;

        query = omit[-(char_('{') >> eol)] >> pair % (eol | (',' >> eol)) >> '}';

        pair  = key >> -(':' >> value);

        key   = omit[*blank] >> '"' >> char_("a-zA-Z_") >> *char_("a-zA-Z_0-9") >> '"';

        value = '"' >> int_ >> '"';

    };

    qi::rule<Iterator, std::map<std::string, int>()> query;
    qi::rule<Iterator, std::pair<std::string, int>()> pair;
    qi::rule<Iterator, std::string()> key;
    qi::rule<Iterator, int()> value;

};

void main(int argc, char** argv)
{
    // Copy json-example.txt right in the std::string
    std::string jsonstr
    (
        (
            std::istreambuf_iterator<char>
            (
                *(std::auto_ptr<std::ifstream>(new std::ifstream("json-example.txt"))).get()
            )
        ),
        std::istreambuf_iterator<char>()
    );

    typedef std::string::iterator StrIterator;

    StrIterator iter_beg = jsonstr.begin();
    StrIterator iter_end = jsonstr.end();

    jsonparser<StrIterator> grammar;

    std::map<std::string,int> output;

    // Parse the given json file
    qi::parse(iter_beg, iter_end, grammatic, output);

    // Output the result
    std::for_each(output.begin(), output.end(), 
            [](const std::pair<std::string, int> &item) -> void 
            { 
                    std::cout << item.first << ":" << item.second << std::endl; 
            });
}

出力:

結果:1
gs:0
ga:0
la:0
lb:0
lc:0
ld:0
ex:0
gd:0
于 2012-04-26T06:44:46.837 に答える