[C++] 291 FLTK : ChatGPTアプリの製作 その20 grepによるjson内文字列検索

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

ChatGPT APIとのやりとりを過去ログとしてjsonファイル保管しています。

質問がなるべくダブらないよう、grepコマンドで事前にjsonファイルを検索できるようにしました。

動画ではまず”FLTK”で調べて21ファイルがヒットしたので”Java”でand検索し、1ファイルに絞り込んでいます。

grepFiles関数はChatGPTに書かせようとしたのですが、どう説明してもor検索のコードしか作れないので、こちらでand検索に書き換えました。とは言えdirent構造体を使ってくるあたりは中級以上のエキスパートかと思うほどの熟練度です。

次はJSONの内容をGUI右側に、質問と回答を左側に表示するようにします。

void searchCB(Fl_Widget*, void*){
    // 初期化
    hitShow -> value();
    window -> redraw();

    const char* grepStr = grepInput -> value();
    cout << "grepStr: " << grepStr << endl;

    stringstream iss(grepStr);
    vector<string> words;
    string word;
    while (getline(iss, word, ' ')) {
        words.push_back(word);
    }
    for (const auto& w : words) {
        cout << "word: " << w << endl;
    }

    string dirPath = "/ChatGPT";
    vector<string> paths = grepFiles(words, dirPath);
    for (const auto& p : paths) {
        cout << "path: " << p << endl;
    }

    int pathsNum = paths.size();
    cout << "HITファイル数: " << pathsNum << endl;

    string pathsNumStr;
    if (pathsNum < 10){
        pathsNumStr = to_string(pathsNum) + " / " + to_string(pathsNum);
    } else {
        pathsNumStr = to_string(pathsNum);
    }

    hitShow -> value(pathsNumStr.c_str());
}

vector<string> grepFiles(const vector<string>& words, const string& path) {
    vector<string> result;
    DIR* dir = opendir(path.c_str());

    if (!dir) {
        cerr << "Error: opendir() failed." << endl;
        return result;
    }

    struct dirent* entry;
    while ((entry = readdir(dir)) != nullptr) {
        if (entry->d_type == DT_REG) { // regular file
            string filePath = path + "/" + entry->d_name;
            string command = "grep -l ";

            int count = 0;
            for (const auto& word : words) {
                if (count == 0){
                    command += word + " \"" + filePath + "\"";
                } else {
                    command += "| grep " + word;
                }
                count++;
            }

            // cout << "command:\n" << command << endl;
            
            FILE* pipe = popen(command.c_str(), "r");
            if (!pipe) {
                cerr << "Error: popen() failed." << endl;
                continue;
            }
            char buffer[256];
            if (fgets(buffer, sizeof(buffer), pipe) != nullptr) {
                result.emplace_back(filePath);
            }
            pclose(pipe);
        }
    }
    closedir(dir);
    return result;
}

[C++] 290 FLTK : ChatGPTアプリの製作 その19 マルチプロセス処理の試み fork関数

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

マルチスレッドの次はマルチプロセスです。

fork関数を使って別のプロセスIDを作成しましたが、プログラムはそこで停止しました。

CoreFoundationはfork()をサポートしていないそうです。POSIX標準なのでLinuxでのみ使用可能とのこと。

void processA() {
    std::cout << "ProcessA: PID = " << getpid() << std::endl;
    sendCB_A();
}

void processB() {
    std::cout << "ProcessB: PID = " << getpid() << std::endl;
    timerCallback(nullptr);
}

void sendCB(Fl_Widget*, void*) {
    sendBool = true;

    pid_t pidA, pidB;

    pidA = fork();
    if (pidA == 0) { // 子プロセスA
        processA();
        return;
    }
    else if (pidA > 0) { // 親プロセス
        std::cout << "Parent process: PID = " << getpid() << std::endl;

        pidB = fork();
        if (pidB == 0) { // 子プロセスB
            processB();
            return;
        }
        else if (pidB > 0) { // 親プロセス
            waitpid(pidA, NULL, 0);
            waitpid(pidB, NULL, 0);
        }
        else { // forkに失敗した場合
            std::cerr << "fork() failed." << std::endl;
            return;
        }
    }
    else { // forkに失敗した場合
        std::cerr << "fork() failed." << std::endl;
        return;
    }
}
Parent process: PID = 62590
ProcessA: PID = 62601
question1回目
ChatGPTとは
requestData: {"model":"gpt-3.5-turbo", "messages":[{"role":"system","content":""},{"role":"user","content":"ChatGPTとは"}], "temperature":0.0}
ProcessB: PID = 62602
The process has forked and you cannot use this CoreFoundation functionality safely. You MUST exec().
Break on __THE_PROCESS_HAS_FORKED_AND_YOU_CANNOT_USE_THIS_COREFOUNDATION_FUNCTIONALITY___YOU_MUST_EXEC__() to debug.
The process has forked and you cannot use this CoreFoundation functionality safely. You MUST exec().
Break on __THE_PROCESS_HAS_FORKED_AND_YOU_CANNOT_USE_THIS_COREFOUNDATION_FUNCTIONALITY___YOU_MUST_EXEC__() to debug.
The process has forked and you cannot use this CoreFoundation functionality safely. You MUST exec().