C++ Builder XE4 > JSON > TStringGridのJSONファイル保存 > TJSONArrayを使用


動作環境
C++ Builder XE4
秀丸エディタ Version 8.79

処理概要

  • TStringGridに項目と値が入っている
    • 項目は横に並ぶ
    • 複数データは縦に並ぶ
  • JSONファイルに保存する

参考

C++ Builder実装を参考にしました。

データ

#includeにて.csv定義したファイルを使います。

例:

data180419.csv
"name", "age", "type",
"7of9", "120", "borg",
"Janeway", "40", "human",
"Odo", "250", "shapeShifter",

上記のファイルは「プロジェクトファイル(.cbproj)」が置いているファイルに用意します。

code v0.1

Unit1.h
//---------------------------------------------------------------------------

#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <System.Classes.hpp>
#include <Vcl.Controls.hpp>
#include <Vcl.StdCtrls.hpp>
#include <Vcl.Forms.hpp>
#include <Vcl.Grids.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published:    // IDE で管理されるコンポーネント
    TStringGrid *StringGrid1;
    TButton *B_toJSON;
    void __fastcall B_toJSONClick(TObject *Sender);
private:    // ユーザー宣言
    void __fastcall makeTestData(void);
public:     // ユーザー宣言
    __fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif
Unit1.cpp
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include <DBXJSON.hpp> // for JSON
#include <memory> // for unique_ptr
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------

/*
v0.1 Apr. 19, 2018
  - add B_toJSONClick()
    + JSONArrayでファイル書込み
  - add [kGroupName]
  - add [kSaveFile]
  - add makeTestData()
  - add kTitileAndData[][]
  - add [NUM_ITEM]
*/


__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
    makeTestData();
}
//---------------------------------------------------------------------------
// StringGridへのテストデータ作成
//
#define NUM_ITEM (3)  // 項目数 (例: 3 for "name, age, type")

// StringGrid用データ
static const String kTitileAndData[][NUM_ITEM] =
{
#include "data180419.csv"
};

void __fastcall TForm1::makeTestData(void)
{
    StringGrid1->FixedRows = 1; // タイトルは1行
    StringGrid1->FixedCols = 0; // 固定列はなし
    StringGrid1->ColCount = NUM_ITEM;

    int rowCnt = sizeof(kTitileAndData) / sizeof(kTitileAndData[0]);

    for(int ri=0; ri < rowCnt; ri++) {  // ri: row index
        for(int ci=0; ci < NUM_ITEM; ci++) {  // ci: column index
            StringGrid1->Cells[ci][ri] = kTitileAndData[ri][ci];
        }
    }

}
//---------------------------------------------------------------------------
// JSON処理

static const String kSaveFile = L"out180419.JSON";  // 出力ファイル
static const String kGroupName = L"member";  // TJSONArrayを格納するグループ名

void __fastcall TForm1::B_toJSONClick(TObject *Sender)
{
    // 1. JSON用意
    TJSONObject *json = new TJSONObject();  // ファイル保存用JSON
    TJSONArray *jary = new TJSONArray();  // グループ用JSONArray

    json->AddPair(kGroupName, jary);

    TJSONObject *member;  // グループ内のメンバー用JSON
    for(int ri=1; ri < StringGrid1->RowCount; ri++) {  // ri: row index
        member = new TJSONObject();
        for(int ci=0; ci < NUM_ITEM; ci++) {  // ci: column index
            String key = StringGrid1->Cells[ci][0];  // 0: 1行目(title)を取る
            String value = StringGrid1->Cells[ci][ri];
            if (value.Length() == 0) { // 空データ
                break;
            }
            member->AddPair(key, value);
        }
        if (member->Size() > 0) {
            jary->AddElement(member);
        }
    }

    // 2. ファイル保存
    std::unique_ptr<TStringList> sl(new TStringList);
    sl->Add( json->ToString() );
    sl->SaveToFile(kSaveFile);

    // 3. 手仕舞い
    //member->Free(); // Error: 無効なポインタ操作
    //jary->Free(); // Error: 無効なポインタ操作
    json->Free();

    ShowMessage(L"Saved to [" + kSaveFile + L"]");
}
//---------------------------------------------------------------------------

実行例

結果ファイル:

out180419.JSON
{"member":[{"name":"7of9","age":"120","type":"borg"},{"name":"Janeway","age":"40","type":"human"},{"name":"Odo","age":"250","type":"shapeShifter"}]}

下記は、JSON Pretty Linter Ver3にて整形後
関連:onlineTool > JSON > JSON整形 > JSON-Viewer (JSON Pretty Linter Ver3)

{
    "member": [
        {
            "name": "7of9",
            "age": "120",
            "type": "borg"
        },
        {
            "name": "Janeway",
            "age": "40",
            "type": "human"
        },
        {
            "name": "Odo",
            "age": "250",
            "type": "shapeShifter"
        }
    ]
}

ひっかかり

memberとjaryのFree()で「無効なポインタ操作」となる。

link

C++ Builder + JSON関連