[C++] 279 FLTK : ChatGPTアプリの製作 その8 コードをFl_Text_Displayに表示・改良

[M1 Mac, Monterey 12.6.3, clang 13.0.0, FLTK 1.3.8, ChatGPT Plus, NO IDE]

ChatGPTから得られた回答を一旦JSONに格納してから取り出すという手順が間違いの元でした。

回答の生データをそのままFl_Text_Displayに表示してから、JSONに格納するようにしました。

これで可読性が大幅に改善しました。

ただJSONに収まった時点でprintf(“%s\n”,str)のようなコード中の改行文字とエスケープシーケンスとしてリテラル化した改行文字が混在してしまうので完全な復元ができない、という問題を抱えたままです。

自分で簡単なパーサー(解析器)を作るしかないのかもしれません。

vector<string> getCode(string str){
    vector<string> codes;
    size_t start_pos = str.find("```");
    while (start_pos != string::npos) {
        size_t end_pos = str.find("```", start_pos + 1);
        if (end_pos != string::npos) {
            code = str.substr(start_pos + 3, end_pos - start_pos - 3);

            size_t start_pos2 = code.find("#");
            code.erase(0, start_pos2);
            codes.push_back(code);
            cout << "getCode内code:\n" << code << endl;

            str.erase(start_pos, end_pos - start_pos + 3);
            cout << "getCode内str:\n" << str << endl;
        }
        start_pos = str.find("```");
    }

    return codes;
}

[C++] 278 FLTK : ChatGPTアプリの製作 その7 コードをFl_Text_Displayに表示

[M1 Mac, Monterey 12.6.3, clang 13.0.0, FLTK 1.3.8, ChatGPT Plus, NO IDE]

これはかなり手こずりました。ChatGPTからは有益なヒントを得られず、自力解決でした。かなり泥臭い手法です。

ChatGPTから受け取った回答をJSON解析するため、改行文字やダブルクォートをリテラルにしているので、これらを元に戻しました。printf(\”%s\n\”, content_cstr);のような置き換える必要のないところまで改行になってしまいますが、これ位はしかたないです。

// code取り出し&表示
    vector<string> codes;
    size_t start_pos = content2.find("```");
    while (start_pos != string::npos) {
        size_t end_pos = content2.find("```", start_pos + 1);
        if (end_pos != string::npos) {
            code = content2.substr(start_pos + 3, end_pos - start_pos - 3);

            size_t start_pos2 = code.find("#");
            code.erase(0, start_pos2);
            codes.push_back(code);
            cout << "code: " << code << endl;

            content2.erase(start_pos, end_pos - start_pos + 3);
            cout << "content2: " << content2 << endl;
        }
        start_pos = content2.find("```");
    }

    Fl_Text_Buffer* bufferCode = new Fl_Text_Buffer();
    string codeStr = codes[0];

    pos = 0;
    while ((pos = codeStr.find("\\n", pos)) != string::npos) {
        codeStr.replace(pos, 2, "\n");
        pos += 2;
    }
    pos = 0;
    while ((pos = codeStr.find("\\n", pos)) != string::npos) {
        codeStr.replace(pos, 2, "\n");
        pos += 2;
    }
    pos = 0;
    while ((pos = codeStr.find('\\', pos)) != string::npos) {
        codeStr.erase(pos, 1);
        pos += 2;
    }

    bufferCode -> text(codeStr.c_str());
    codeDisplay -> buffer(bufferCode);
    codeDisplay -> wrap_mode(Fl_Text_Display::WRAP_AT_BOUNDS, 5);