[C++] 311 インクルードパスの確認方法 #include_nextトラブル

[M1 Mac, Ventura 13.3.1, clang 13.0.0]

MacOSをMontereyからVenturaに上げるとコンパイル時に以下のエラーが出るようになりました。

fatal error: 'stdio.h' file not found
#include_next <stdio.h>

Command Line Toolsを入れ直してもダメでXcodeを削除したりしているといつの間にか正常になりました。Xcodeを解決後に再インストールしても問題ありませんでした。MacOSをバージョンアップするたびにこの種のトラブルが必ず起こるので困ったものです。

rm -rf /Library/Developer/CommandLineTools
xcode-select --install

ところで#include_nextはインクルードパスにある別の同名ヘッダファイルを読み込む指示です。インクルードパスは以下のコマンドで確認できます。

clang++ -x c++ -v -E /dev/null
$ clang++ -x c++ -v -E /dev/null
Apple clang version 14.0.3 (clang-1403.0.22.14.1)
Target: arm64-apple-darwin22.4.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin
 "/Library/Developer/CommandLineTools/usr/bin/clang" -cc1 -triple arm64-apple-macosx13.0.0 -Wundef-prefix=TARGET_OS_ -Wdeprecated-objc-isa-usage -Werror=deprecated-objc-isa-usage -Werror=implicit-function-declaration -E -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name null -mrelocation-model pic -pic-level 2 -mframe-pointer=non-leaf -fno-strict-return -ffp-contract=on -fno-rounding-math -funwind-tables=1 -fobjc-msgsend-selector-stubs -target-sdk-version=13.3 -fvisibility-inlines-hidden-static-local-var -target-cpu apple-m1 -target-feature +v8.5a -target-feature +crc -target-feature +lse -target-feature +rdm -target-feature +crypto -target-feature +dotprod -target-feature +fp-armv8 -target-feature +neon -target-feature +fp16fml -target-feature +ras -target-feature +rcpc -target-feature +zcm -target-feature +zcz -target-feature +fullfp16 -target-feature +sm4 -target-feature +sha3 -target-feature +sha2 -target-feature +aes -target-abi darwinpcs -fallow-half-arguments-and-returns -debugger-tuning=lldb -target-linker-version 857.1 -v -fcoverage-compilation-dir=/Users/user -resource-dir /Library/Developer/CommandLineTools/usr/lib/clang/14.0.3 -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk -I/usr/local/include -stdlib=libc++ -internal-isystem /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/v1 -internal-isystem /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/local/include -internal-isystem /Library/Developer/CommandLineTools/usr/lib/clang/14.0.3/include -internal-externc-isystem /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include -internal-externc-isystem /Library/Developer/CommandLineTools/usr/include -Wno-reorder-init-list -Wno-implicit-int-float-conversion -Wno-c99-designator -Wno-final-dtor-non-final-class -Wno-extra-semi-stmt -Wno-misleading-indentation -Wno-quoted-include-in-framework-header -Wno-implicit-fallthrough -Wno-enum-enum-conversion -Wno-enum-float-conversion -Wno-elaborated-enum-base -Wno-reserved-identifier -Wno-gnu-folding-constant -fdeprecated-macro -fdebug-compilation-dir=/Users/user -ferror-limit 19 -stack-protector 1 -fstack-check -mdarwin-stkchk-strong-link -fblocks -fencode-extended-block-signature -fregister-global-dtors-with-atexit -fgnuc-version=4.2.1 -fno-cxx-modules -no-opaque-pointers -fcxx-exceptions -fexceptions -fmax-type-align=16 -fcommon -fcolor-diagnostics -clang-vendor-feature=+disableNonDependentMemberExprInCurrentInstantiation -fno-odr-hash-protocols -clang-vendor-feature=+enableAggressiveVLAFolding -clang-vendor-feature=+revert09abecef7bbf -clang-vendor-feature=+thisNoAlignAttr -clang-vendor-feature=+thisNoNullAttr -mllvm -disable-aligned-alloc-awareness=1 -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o - -x c++ /dev/null
clang -cc1 version 14.0.3 (clang-1403.0.22.14.1) default target arm64-apple-darwin22.4.0
ignoring nonexistent directory "/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/local/include"
ignoring nonexistent directory "/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/Library/Frameworks"
#include "..." search starts here:
#include <...> search starts here:
 /usr/local/include
 /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/v1
 /Library/Developer/CommandLineTools/usr/lib/clang/14.0.3/include
 /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include
 /Library/Developer/CommandLineTools/usr/include
 /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks (framework directory)
End of search list.
# 1 "/dev/null"
# 1 "<built-in>" 1
# 1 "<built-in>" 3
# 428 "<built-in>" 3
# 1 "<command line>" 1
# 1 "<built-in>" 2
# 1 "/dev/null" 2
$ clang++ -x c++ -v -E /dev/null
Apple clang version 14.0.3 (clang-1403.0.22.14.1)
Target: arm64-apple-darwin22.4.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
 "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang" -cc1 -triple arm64-apple-macosx13.0.0 -Wundef-prefix=TARGET_OS_ -Wdeprecated-objc-isa-usage -Werror=deprecated-objc-isa-usage -Werror=implicit-function-declaration -E -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name null -mrelocation-model pic -pic-level 2 -mframe-pointer=non-leaf -fno-strict-return -ffp-contract=on -fno-rounding-math -funwind-tables=1 -fobjc-msgsend-selector-stubs -target-sdk-version=13.3 -fvisibility-inlines-hidden-static-local-var -target-cpu apple-m1 -target-feature +v8.5a -target-feature +crc -target-feature +lse -target-feature +rdm -target-feature +crypto -target-feature +dotprod -target-feature +fp-armv8 -target-feature +neon -target-feature +fp16fml -target-feature +ras -target-feature +rcpc -target-feature +zcm -target-feature +zcz -target-feature +fullfp16 -target-feature +sm4 -target-feature +sha3 -target-feature +sha2 -target-feature +aes -target-abi darwinpcs -fallow-half-arguments-and-returns -debugger-tuning=lldb -target-linker-version 857.1 -v -fcoverage-compilation-dir=/Volumes/DATA_m1/code/cpp/projects/SFTPAssist -resource-dir /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/14.0.3 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk -I/usr/local/include -stdlib=libc++ -internal-isystem /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/c++/v1 -internal-isystem /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/local/include -internal-isystem /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/14.0.3/include -internal-externc-isystem /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include -internal-externc-isystem /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include -Wno-reorder-init-list -Wno-implicit-int-float-conversion -Wno-c99-designator -Wno-final-dtor-non-final-class -Wno-extra-semi-stmt -Wno-misleading-indentation -Wno-quoted-include-in-framework-header -Wno-implicit-fallthrough -Wno-enum-enum-conversion -Wno-enum-float-conversion -Wno-elaborated-enum-base -Wno-reserved-identifier -Wno-gnu-folding-constant -fdeprecated-macro -fdebug-compilation-dir=/Volumes/DATA_m1/code/cpp/projects/SFTPAssist -ferror-limit 19 -stack-protector 1 -fstack-check -mdarwin-stkchk-strong-link -fblocks -fencode-extended-block-signature -fregister-global-dtors-with-atexit -fgnuc-version=4.2.1 -fno-cxx-modules -no-opaque-pointers -fcxx-exceptions -fexceptions -fmax-type-align=16 -fcommon -fcolor-diagnostics -clang-vendor-feature=+disableNonDependentMemberExprInCurrentInstantiation -fno-odr-hash-protocols -clang-vendor-feature=+enableAggressiveVLAFolding -clang-vendor-feature=+revert09abecef7bbf -clang-vendor-feature=+thisNoAlignAttr -clang-vendor-feature=+thisNoNullAttr -mllvm -disable-aligned-alloc-awareness=1 -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o - -x c++ /dev/null
clang -cc1 version 14.0.3 (clang-1403.0.22.14.1) default target arm64-apple-darwin22.4.0
ignoring nonexistent directory "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/local/include"
ignoring nonexistent directory "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/Library/Frameworks"
#include "..." search starts here:
#include <...> search starts here:
 /usr/local/include
 /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/c++/v1
 /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/14.0.3/include
 /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include
 /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include
 /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks (framework directory)
End of search list.
# 1 "/dev/null"
# 1 "<built-in>" 1
# 1 "<built-in>" 3
# 428 "<built-in>" 3
# 1 "<command line>" 1
# 1 "<built-in>" 2
# 1 "/dev/null" 2

今回のトラブルで、私のような非IDE派はCommand Line Toolsさえあればプログラミングできる、つまりXcodeがなくても問題ないということを再確認しました。Xcodeは20GB超えの重量アプリですから、ストレージ不足になったら真っ先に削除するようにします。

[C++] 310 FLTK : 長整数型を引数とするcallback関数 その2

[M1 Mac, Ventura 13.3.1, clang 13.0.0, FLTK 1.3.8, NO IDE]

callback関数の引数に長整数を使うことで第1引数の動作関数に引数として追加できます。

任意の長整数により動作関数の内容を条件分けできます。例えばFileChooserで選んだファイルパスの表示先を変えることが出来たりします。

使用頻度は高くないですが、たまに使おうとすると殆ど忘れてしまっているので再度記事にしておきます。構造がややこしくて共同開発であれば現場を混乱させそうな内容です。

久しぶりにC++のコードを書きましたが、だいぶPythonになじんでいたので調子が出ないです。

// fileFcBtn
fileFcBtn = new Fl_Button(245,108,30,20,"...");
fileFcBtn->color(fl_rgb_color(112,128,144));
fileFcBtn->labelcolor(fl_rgb_color(255,239,213));
fileFcBtn->labelsize(14);
fileFcBtn->callback(FileChooserCB,1); // 長整数1を渡す

// toFcBtn
toFcBtn = new Fl_Button(245,143,30,20,"...");
toFcBtn->color(fl_rgb_color(112,128,144));
toFcBtn->labelcolor(fl_rgb_color(255,239,213));
toFcBtn->labelsize(14);
toFcBtn->callback(FileChooserCB,2); // 長整数2を渡す
void FileChooserCB(Fl_Widget*, long num) {
    int fc;
    string appdir = "/";
    int onoff_dir = dir_rbtn->value();

    if (onoff_dir == 1){
        fc = 4; // FileChooser::DIRECTORY
    } else {
        fc = 0; // FileChooser::SINGLE
    }

    int x_win = window->x_root();
    int y_win = window->y_root();
    cout<<"x_win "<< x_win <<" y_win "<< y_win <<endl;

    chooser = new FileChooser(appdir.c_str(), 
                        "*.*",
                        fc,
                        "File/Dir Chooser",490,380, num
                        );
    
    chooser->resize(x_win+85,y_win+50,490,380);
    chooser->set_modal();
    chooser->Fl_Window::show();

    while(chooser->Fl_Window::shown()){
        Fl::wait();
    }
}
FileChooser::FileChooser(const char *d, const char *p, 
int t, const char *title,int w,int h, long num)
	:Fl_Window(w,h,title),Fl_File_Chooser(d,p,t,title){

<中略>

btnOK = new Fl_Return_Button(313, 345, 85, 25, "OK");
		if (num==1){
			btnOK->callback((Fl_Callback*)btnOKCB);
		} else {
			btnOK->callback((Fl_Callback*)btnOKCB2);
		}
void btnOKCB(Fl_Return_Button*, void*)
{
	const char* file = inputFileName->value();

	file_input->value("");
	file_input->value(file);
	chooser->Fl_Window::hide();
}

void btnOKCB2(Fl_Return_Button*, void*)
{
	const char* file = inputFileName->value();

	to_input->value("");
	to_input->value(file);
	chooser->Fl_Window::hide();
}
FileChooser
FileChooser選択パスの表示先がFILE/DIR欄に固定されていてTO欄が使えていない
修正後はボタン別に表示先を変えられるようになった
類似記事

[C++] 309 ファイルの生成日時を文字列にする

[M1 Mac, Monterey 12.6.3, clang 13.0.0, ChatGPT API(gpt-3.5-turbo), NO IDE]

ChatGPTに作ってもらいました。何度かトライしてようやく成功です。

最初の回答を修正させてハマったので、全く別の方法を考えさせました。

一見単純なコードですが、stat構造体を知らないと書けません。

ところでAIの情報を毎日チェックしていますが、ChatGPTの優秀さが際立つばかりといった印象です。

AI開発停止運動とやらは、OpenAI始め先行開発群に追いつけそうもない焦りの現れでしょうか。

MDファイルをJSONに変換して生成日時をファイル名に追加
#include <sys/stat.h>

string getCreationTime(const char* filePath) {
    struct stat attr;
    if (stat(filePath, &attr) == -1) {
        return "";
    }

    char buffer[16];
    strftime(buffer, sizeof(buffer), "%y%m%d_%H%M%S", localtime(&attr.st_birthtimespec.tv_sec));

    return buffer;
}

[C++] 308 FLTK : ChatGPTアプリの製作 その35 md→json変換 その2

[M1 Mac, Monterey 12.6.3, clang 13.0.0, FLTK 1.3.8, ChatGPT API(gpt-3.5-turbo), NO IDE]

昨日ChatGPTに書いてもらったコードを叩き台にして手を入れ主要な部分を作成しました。

細かいところで色々ややこしかったので、coutデバッグの痕跡を残したままアップしておきます。前半のwhile文はこちらの意図が伝わってなかったのか大分修正しました。後半のfor文が完璧だったのはさすがです。

あとはmdファイルの生成日時をファイル名の先頭に付けたら完成になります。

これでiPadやスマートフォンでのやりとりもChatGPTアプリで閲覧できるようになります。

変換jsonファイルの内容確認
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <sstream>
#include <nlohmann/json.hpp>

using namespace std;
using json = nlohmann::json;

int main() {
    ifstream ifs("test.md");
    string line;
    vector<string> user_messages;
    vector<string> assistant_messages;
    bool is_user = false;
    string assistant_msg;
    string user_msg;

    cout << "初期化通過" << endl;

    while (getline(ifs, line)) {
        cout << "while通過" << endl;

        if (line.empty()) {
            if (is_user) {
                is_user = false;
            }
            cout << "empty通過" << endl;
        } else if (line[0] == '>') { // user
            if (assistant_msg != ""){
                assistant_messages.push_back(assistant_msg);
                cout << "assistantベクター追加" << endl;
                assistant_msg = "";
            }

            is_user = true;
            cout << "user : " << line.substr(2) << endl;
            string user_msg = line.substr(2) + "\n";
            user_messages.push_back(user_msg);
        } else {
            if (is_user) {
                cout << "user2行目以降 : " << line << endl;
                user_msg += line + "\n";
                cout << "user文字列追加" << endl;

            } else {
                if (user_msg != ""){
                    user_messages.push_back(user_msg);
                    cout << "userベクター追加" << endl;
                    user_msg = "";
                }

                cout << "assistant : " << line << endl;
                assistant_msg += line + "\n";
                cout << "assistant文字列追加" << endl;
            }
        }
    }
    assistant_messages.push_back(assistant_msg);
    cout << "assistantベクター最終追加" << endl;

    cout << "getline通過" << endl;

    json root;
    json messages = json::array();
    for (int i = 0; i < user_messages.size(); i++) {
        json message;
        message["content"] = user_messages[i];
        message["role"] = "user";
        messages.push_back(message);
        message["content"] = assistant_messages[i];
        message["role"] = "assistant";
        messages.push_back(message);
    }
    root["messages"] = messages;
    root["model"] = "gpt-3.5-turbo";
    root["temperature"] = 0.0;

    ofstream ofs("output.json");
    ofs << root.dump(4);

    return 0;
}

[C++] 307 FLTK : ChatGPTアプリの製作 その34 md→json変換

[M1 Mac, Monterey 12.6.3, clang 13.0.0, FLTK 1.3.8, ChatGPT API(gpt-3.5-turbo), NO IDE]

iPadでChatGPTを使う場合は公式Webを使います。そこでのやりとりはWebラッパーでmdファイルとしてダウンロードします。

そのmdファイルを自製ChatGPTアプリでjsonファイルに変換できるよう開発を進めています。

最初はRustで製作されたWebラッパーを改変してjsonとしてダウンロードできるようにしようかとも考えたんですが、Rustで書くとJavaのヌルポ攻勢と同様の例外処理対応に追われるのが目に見えているので、やめておくことにしました。

取りあえずChatGPTに叩き台のコードを書いてもらいました。

ところでGPT-4のwaitlistに登録して2週間が経とうとしていますが、まだAPIで使えません。やはり重課金ユーザー優先ということでしょう。当方かなり使ったつもりでもまだ供与された18ドルに遠く及ばない2.8ドルです。

RWKVなど有望なLLMが話題に上がっていて、いよいよローカルChat Botの実現が見えてきました。今のところRTX3080位ないと厳しいらしく、どうするか考えています。

ただTwitterを見る限りキャッチアップしているのは画像生成AI界隈の方ばかりで、その分野に全く興味がない者としてそろそろ潮時とも思えます。プログラマ系の方々は水面下に潜った感がありますね。そりゃTwitterばかり見てたらコードもろくに書けません。

ChatGPTアプリ製作開始から26日経過し、平常モードに戻るタイミングかもしれません。

Q:
以下のコードをC++で書いて下さい。
mdファイルをjsonファイルに変換する。
1.mdファイル
不等号の行はrole:userのcontent
改行コードが2回続き、次の行はrole:assistantのcontent
2.jsonファイル
keyはmessages, model, temperatureの3つ。
modelのvalueはgpt-3.5-turbo
temperatureのvalueは0.0
jsonの例は以下の通り
{
“messages”: [
{
“content”: “”,
“role”: “system”
},
{
“content”: “FLTKのプログラムがFl_Buttonを自動クリックするコードを書いて下さい”,
“role”: “user”
},
{
“content”: “以下は、FLTKのプログラムでFl_Buttonを自動クリックするコードの例です。\n\nc++\n#include <FL/Fl.H>\n#include <FL/Fl_Window.H>\n#include <FL/Fl_Button.H>\n\nint main(int argc, char **argv) {\n Fl_Window *window = new Fl_Window(200, 200, \"Auto Click\");\n Fl_Button *button = new Fl_Button(50, 50, 100, 50, \"Click Me\");\n\n // 自動クリックする\n button->do_callback();\n\n window->end();\n window->show(argc, argv);\n return Fl::run();\n}\n\n\nこの例では、Fl_Buttonオブジェクトのdo_callback()メソッドを呼び出すことで、ボタンを自動的にクリックしています。このメソッドは、ボタンがクリックされたときに呼び出されるコールバック関数を実行します。”,
“role”: “assistant”
},
{
“content”: “これまでの質問回答の内容から15文字程度で日本語タイトルを考えて下さい。英単語が混ざってもかまいません。”,
“role”: “user”
},
{
“content”: “FLTKで自動クリックする方法”,
“role”: “assistant”
}
],
“model”: “gpt-3.5-turbo”,
“temperature”: 0.0
}

A:
以下がC++でのコード例になります。

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <nlohmann/json.hpp>

using json = nlohmann::json;

int main() {
    // mdファイルを読み込む
    std::ifstream ifs("1.md");
    std::string md((std::istreambuf_iterator<char>(ifs)), std::istreambuf_iterator<char>());

    // mdファイルを改行コードで分割する
    std::vector<std::string> lines;
    std::string line;
    std::istringstream iss(md);
    while (std::getline(iss, line)) {
        lines.push_back(line);
    }

    // jsonオブジェクトを作成する
    json j;
    j["messages"] = json::array();
    j["model"] = "gpt-3.5-turbo";
    j["temperature"] = 0.0;

    // mdファイルの内容をjsonオブジェクトに追加する
    std::string role = "user";
    for (const auto& line : lines) {
        if (line.empty()) {
            role = "assistant";
            continue;
        }
        j["messages"].push_back({
            {"content", line},
            {"role", role}
        });
    }

    // jsonファイルに書き込む
    std::ofstream ofs("2.json");
    ofs << j.dump(4) << std::endl;

    return 0;
}

このコードでは、まずmdファイルを読み込み、改行コードで分割して各行を処理します。次に、jsonオブジェクトを作成し、mdファイルの内容をjsonオブジェクトに追加します。最後に、jsonファイルに書き込みます。

[C++] 306 FLTK : 文字列をユニコードに変換 漢字変換修正 UTF-16

[M1 Mac, Monterey 12.6.3, clang 13.0.0, FLTK 1.3.8, ChatGPT API(gpt-3.5-turbo), NO IDE]

前回の記事で漢字変換がおかしかった所を修正しました。

UTF-8のままではマルチバイト文字を1つのユニコードとして認識できないため、UTF-16に変換する必要があります。

wstring_convertクラスを使ってUTF-8からUTF-16に変換しています。

#include <iostream>
#include <string>
#include <codecvt>

void convertCB(Fl_Widget*, void*) {
    std::stringstream unicode;
    const char* chr = convertInput -> value();

    std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
    std::wstring unicode_str = converter.from_bytes(chr);
    for (wchar_t c : unicode_str) {
        unicode << std::hex << std::uppercase << static_cast<int>(c) << " ";
    }

    browser->add((unicode.str()).c_str());
}

[C++] 305 FLTK : 文字列をユニコードに変換 

[M1 Mac, Monterey 12.6.3, clang 13.0.0, FLTK 1.3.8, ChatGPT API(gpt-3.5-turbo), NO IDE]

自製アプリに文字列をユニコードに変換する機能を実装しました。

下図のようにファイル名に改行コードLFが混入していることが分かります。

漢字の変換がおかしいですが、後日修正します。

void convertCB(Fl_Widget*, void*) {
    std::stringstream unicode;
    const char* chr = convertInput -> value();
    for (int i = 0; chr[i] != '\0'; i++) {
        unicode << "\\u" << std::hex << std::setw(4) << std::setfill('0') << (int)chr[i];
    }

    browser->add((unicode.str()).c_str());
}

[C++] 304 FLTK : ChatGPTアプリの製作 その33 Finderの異常表示原因判明

[M1 Mac, Monterey 12.6.3, clang 13.0.0, FLTK 1.3.8, ChatGPT API(gpt-3.5-turbo), NO IDE]

前回の続きです。

Finderのファイル名に?が紛れ込む原因は改行コードの混入でした。

Commander Oneでファイル情報を見てみるとファイル名のところに改行が入っていました。

ChatGPTアプリで返信された回答をGUIに表示する際、コピペがしやすいように文末に改行コードを追加したことが原因でした。

Finderを悪者扱いしてしまい反省です。ChatGPTからも特殊文字が混ざっているとその部分は?になるという指摘がありましたが、正にその通りでした。ファイル名をユニコードU+16進数(U+XXXX)表記させればすぐに分かっていたでしょう。

ただCommander Oneのinfoでようやく分かったように、Finderの方でも改行コードが何らかの形で反映されるように改良していただきたいものです。

この件は解決した一方、.DS_Storeファイルによるmake妨害の件については現在とある検証を実施中です。妨害回避に成功したら報告します。

Commander Oneのinfo : ファイル名が.jsonの手前で改行されている
// 最新回答contentをoutputに表示
Fl_Text_Buffer* buffer = new Fl_Text_Buffer();
output -> buffer(buffer);
buffer -> append(content0.c_str());
buffer -> append("\n");             // ここが余計だった
output -> wrap_mode(Fl_Text_Display::WRAP_AT_BOUNDS, 5);

[C++] 303 FLTK : ChatGPTアプリの製作 その32 Finderの不具合発覚?

[M1 Mac, Monterey 12.6.3, clang 13.0.0, FLTK 1.3.8, ChatGPT API(gpt-3.5-turbo), NO IDE]

ChatGPTアプリでファイル名を色々加工していると?や^Jのような意図しない文字列が紛れ込むようになりました。

C++はUTF-8の扱いが苦手なのでまたかと思いつつコードを修正したものの、どうやっても直りません。

どうやらFinderの不具合のようです。バグまみれだとは思っていましたが、まさかここまでひどいとは。

普段からSpotlight用の.DS_Storeファイルにmakeコマンドの邪魔をされていることも併せてさすがに腹が立ちました。一応ChatGPTを通して弁明を聞いておきました。

ファイル名の最後に?が付くようになった
Commander Oneでは正常に表示される
ChatGPTの意見

[C++] 302 FLTK : ChatGPTアプリの製作 その31 ChatGPTを使って関数作成

[M1 Mac, Monterey 12.6.3, clang 13.0.0, FLTK 1.3.8, ChatGPT API(gpt-3.5-turbo), NO IDE]

ChatGPTにファイル名に任意の文字列を含むものを移動させる関数や削除する関数の中身を作ってもらいました。たった20秒で答えが返ってきます。引数はこちらで考えて完成させました。

汎用性の高い関数を量産することが可能になりました。ネットのレファレンスや逆引き辞典を使うよりもChatGPTに作らせる方が断然速いです。

namespace fs = std::filesystem;

void moveFile(fs::path srcDir, fs::path destDir, const char* str){
    try {
        // 移動元のディレクトリ内のファイルを順に処理
        for (const auto& entry : fs::directory_iterator(srcDir)) {
            // ファイル名にstrを含む場合は移動
            if (entry.path().filename().string().find(str) != std::string::npos) {
                fs::rename(entry.path(), destDir / entry.path().filename());
                std::cout << entry.path() << "を移動しました。" << std::endl;
            }
        }
    } catch (const std::filesystem::filesystem_error& e) {
        std::cerr << "ファイルの移動に失敗しました。" << std::endl;
        std::cerr << e.what() << std::endl;
        return;
    }
    
}

void removeFile(fs::path dirPath, string str){
     try {
        // ディレクトリ内のファイルを順に処理
        for (const auto& entry : fs::directory_iterator(dirPath)) {
            // ファイル名にstrを含む場合は削除
            if (entry.path().filename().string().find(str) != std::string::npos) {
                fs::remove(entry.path());
                std::cout << entry.path() << "を削除しました。" << std::endl;
            }
        }
    } catch (const std::filesystem::filesystem_error& e) {
        std::cerr << "ファイルの削除に失敗しました。" << std::endl;
        std::cerr << e.what() << std::endl;
        return;
    }
}