1. ホーム
  2. c++

[解決済み] QJsonコードの読み方、書き方、印刷方法に関する最小限の例(QJsonDocument、QJsonArray、QJsonObject、QFileを使用)。

2022-03-03 11:10:33

質問

私は、このJsonコードを解析して書くための最小限の完全な実行可能なqtまたはc++コードの例を探しています。

{
    "FirstName": "John",
    "LastName": "Doe",
    "MiddleName": null,
    "Age": 43,

    "Address": {
        "Street": "Downing Street 10",
        "City": "London",
        "Country": "Great Britain"
    },
    "Phone numbers": [
        "+44 1234567",
        "+44 2345678"
    ]
    "Valid":true,
}

  • 上の例は、5つのキーと値のペアを持つオブジェクトで構成されています。値のうち2つは文字列で、1つは数値である。
  • は別のオブジェクトで、最後の1つは配列です。
  • 有効なJSONドキュメントは配列かオブジェクトなので、ドキュメントは常に角括弧か中括弧で始まっています。

EDIT

  • Jsonは 2つ以上 キーと値のペア - 値は 'null' と 'bool' です。

そして、そう、私が見たのは "セーブゲーム例" を表示し、それを理解しようとしました。

しかし、1週間近く経ってから、enumやQVector、3種類のヘッダーファイルのない最小限のサンプルを私のプロジェクトに転送し、コードスニペットを処理することをあきらめました。ウィジェットやコアコードには関係ありません。

私はすでにxmlの読み取りと書き込みのプログラムを成功させたが、私はいくつかの重要なポイントを見逃し、パースと関係があるのかないのか、jsonでエラーが発生するようです。私は、最小限の完全に動作するコード例なしで、それを除外することはできません。

そこで質問です。 Jsonファイルの書き込み、読み出し、印刷を行う最小限のExampleを提供していただけないでしょうか。前もってありがとうございます。

どのように解決するのですか?

他の人の役に立つかもしれないので、すべて把握しました。 Botjeの例には本当に助けられました。 一般に、私はデータを QByteArray を記憶しています。

jsonファイルに格納されているすべての値をアクセスし、また使用するための最小限の例です。

(そうですね、もっとコンパクトに書くこともできたのですが、その方がわかりやすいと思うので、読みやすさを重視して関数/クラス/構造体を割愛しました)

#include <QCoreApplication>
#include <QString>
#include <QVariant>
#include <QFile>
#include <QByteArray>
#include <QTextStream>
#include <QDebug>

//json specific
#include <QJsonParseError>
#include <QJsonDocument>
#include <QJsonArray>
#include <QJsonObject>
#include <QJsonParseError>
#include <QJsonValue>


    void writeJsonFile();
    void readJsonFile();


int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    writeJsonFile();
    readJsonFile();

    return a.exec();
}

void writeJsonFile()
{
    qDebug() << "Write Json File: ";

    //1. Create a QJsonObject and add values to it
    QJsonObject jsonObj;
    jsonObj["FirstName"] = "John";
    //no value will be written as null in the json file
    jsonObj["MiddleName"];
    jsonObj["LastName"] = "Doe";
    jsonObj["Age"] = 43;

    //2. Create Item of Json Object content (object of object)
    QJsonObject jsonItemObj;
    jsonItemObj["Street"] = "Downing Street 10";
    jsonItemObj["City"] = "London";
    jsonItemObj["Country"] = "Great Britain";
    //3. Add jsonItemObj to jsonObj and give it an object Name
    jsonObj["Address"] = jsonItemObj;

    //4. Create jsonArray and fill it with values - similar to filling a vector
    QJsonArray jsonArray;
    jsonArray.append("+44 1234567");
    jsonArray.append("+44 2345678");

    //Add a bool to the Object
    jsonObj["Valid"] = true;

    //5. Add jsonArray to jsonObj and give it an object Name
    jsonObj["Phone numbers"] = jsonArray;
    //(It can also be added to the jsonItemObj to be inline with the Address section)
    //with jsonItemObj["Phone numbers"] = jsonArray or as much objects of objects
    //you need


    /* As I understood it, most Qt classes use a QByteArray to handle data internally
     * because it is really fast/efficient,
     * also QFile QIODevice, it is a good idea to hold the read/write
     * QIODevice data as QByteArray in the Memory
     */

    //6. Create a QByteArray and fill it with QJsonDocument (json formatted)
    QByteArray byteArray;
    byteArray = QJsonDocument(jsonObj).toJson();

    //7. Open a QFile and write the byteArray filled with json formatted data
    //thanks to the QJsonDocument() Class to the file
    QFile file;
    file.setFileName("file.json");
    if(!file.open(QIODevice::WriteOnly)){
        qDebug() << "No write access for json file";
        return;
    }

    //8. finally write the file and close it
    file.write(byteArray);
    file.close();

    //9. Print out the byteArray to the terminal
    QTextStream textStream(stdout);
    textStream << "Rendered json byteArray text: " << endl;
    textStream << byteArray << endl;
}

void readJsonFile()
{
    qDebug() << "Read Json File:";

    //1. Open the QFile and write it to a byteArray and close the file
    QFile file;
    file.setFileName("file.json");
    if(!file.open(QIODevice::ReadOnly)){
        qDebug() << "Json filef couldn't be opened/found";
        return;
    }

    QByteArray byteArray;
    byteArray = file.readAll();
    file.close();

    //2. Format the content of the byteArray as QJsonDocument
    //and check on parse Errors
    QJsonParseError parseError;
    QJsonDocument jsonDoc;
    jsonDoc = QJsonDocument::fromJson(byteArray, &parseError);
    if(parseError.error != QJsonParseError::NoError){
        qWarning() << "Parse error at " << parseError.offset << ":" << parseError.errorString();
        return;
    }

    //3. Create a jsonObject and fill it with the byteArray content, formatted
    //and holding by the jsonDocument Class
    QJsonObject jsonObj;
    jsonObj = jsonDoc.object();

    //4. Now picking the jsonValues and printing them out or do what ever you need
    QJsonValue jsonVal;
    QTextStream textStream(stdout);

    jsonVal = jsonObj.value("FirstName");
    textStream << jsonVal.toString() << endl;

    jsonVal = jsonObj.value("MiddleName");
    //null gets back to an empty fild - added the sting "null/empty" to make it visible
    textStream << jsonVal.toVariant().toString() << "null/empty" << endl;

    jsonVal = jsonObj.value("LastName");
    textStream << jsonVal.toString() << endl;

    //The number has to be converted to an int and than to a string to print it
    jsonVal = jsonObj.value("Age");
    textStream << QString::number(jsonVal.toInt()) << endl;

    //5. Now we need to fill the object of the object. To do that, we need
    //the Item Object and a jsonSubVal object for json without a loop
    QJsonObject jsonItemObj;
    QJsonValue jsonSubVal;

    jsonVal = jsonObj.value(QString("Address"));
    jsonItemObj = jsonVal.toObject();

       jsonSubVal = jsonItemObj["Street"];
       textStream << jsonSubVal.toString() << endl;

       jsonSubVal = jsonItemObj["City"];
       textStream << jsonSubVal.toString() << endl;

       jsonSubVal = jsonItemObj["Country"];
       textStream << jsonSubVal.toString() << endl;

    //6. now the Phone Numbers array with a loop
    QJsonArray jsonArray;
    jsonArray = jsonObj["Phone numbers"].toArray();

    for(int i = 0; i < jsonArray.size(); i++)
        textStream << jsonArray[i].toString() << endl;

    textStream << "or with foreach" << endl;

    foreach(QJsonValue v, jsonArray)
        textStream << v.toString() << endl;

    //7. And finally the bool value:
    jsonVal = jsonObj.value(QString("Valid"));
    textStream << jsonVal.toVariant().toString() << endl;

    textStream << "or as number, not a string: ";

    textStream << (QString::number(jsonVal.toInt())) << endl;

    textStream << "\nThe whole file as printed in the file \n" <<
                  jsonDoc.toJson(QJsonDocument::Indented);