io.open 保存したテキストファイルを読み込む – FlyWithLua

2023年2月18日

テキストに保存されたファイル全てを一気に読み込み表示する。

9行目で「SCRIPT_DIRECTORY..」つまり、FlWithLua内にあるscriptフォルダ内にある「read.txt」に記述されたテキストの内容を読み込み表示することができる。
lineは全てのテキストを読み込むので、これでは行を指定して読み込むことはできない。

-- imguiはフローティングウィンドウ内でのみ機能するため、最初に作成する必要があります。
demo_wnd = float_wnd_create(250, 150, 1, true)
float_wnd_set_title(demo_wnd, "imgui Demo") --ウィンドウのタイトル
float_wnd_set_imgui_builder(demo_wnd, "build_demo")
 
-- imguiウインドウ内で実行するスクリプト -------------------------------------------------
function build_demo(wnd, x, y)
 
  local file = io.open(SCRIPT_DIRECTORY.."read.txt", "r")   -- read.txtの内容を読み込む。
  for line in file:lines() do   --ファイル内にあるだけの行を読み込む
    --imguiでTextUnformattedはテキストを描く関数
    imgui.TextUnformatted(line)	--ここに上の「line」変数を読み込む
  end
 
  file:close() -- 最後にf:closeでファイルを閉じる
end

指定のテキストを読み込むことができる。

テキストを用意する。読み込むテキストは区切りに「, 」を使う。最後の「, 」は入れない。入れると「,」が表示されてしまう。テキストはファイルの一番上から書き込む必要がある。

実際に読み込んだら、このように最後に「,」が表示される。

上の状態のテキストなら、下のスクリプトで指定の文字を読み込む事ができる。
テキストの数と指定の数を合わせる必要がある。そうでないと表示されない。

txtLine_1, txtLine_2, txtLine_3 = string.match(line, “(.-)%,(.-)%,(.+)”)
string.matchは文字列をマッチさせる関数。””内はマッチさせる方法、よくわからないが「, 」で区切られる内容をマッチさせているようだ。

-- imguiはフローティングウィンドウ内でのみ機能するため、最初に作成する必要があります。
demo_wnd = float_wnd_create(250, 150, 1, true)
float_wnd_set_title(demo_wnd, "imgui Demo") --ウィンドウのタイトル
float_wnd_set_imgui_builder(demo_wnd, "build_demo")

-- imguiウインドウ内で実行するスクリプト -------------------------------------------------
function build_demo(wnd, x, y)
    local file = io.open(SCRIPT_DIRECTORY .. "read.txt", "r")
    for line in file:lines() do
        txtLine_1, txtLine_2, txtLine_3 = string.match(line, "(.-)%,(.-)%,(.+)")
        imgui.TextUnformatted(txtLine_1)
        imgui.TextUnformatted(txtLine_2)
        imgui.TextUnformatted(txtLine_3)
    end
    file:close() -- 最後にf:closeでファイルを閉じる
end

string.match(line, “(.-)%,(.-)%,(.+)”) この状態では最後に「,」を追加すると「,」が消える。
string.match(line, “(.-)%,(.-)%,(.+),“) このように最後に赤の「,」を追加する。以下のように,が消えた。

inputに読み込む

imgui.TextUnformattedは読み込むことができたのでInputTextでも同じように読むことができる。ファイルは上と同じように「,」区切りである必要がある。最後の「,」を消す方法で作成している。

14行目の「string.match」で行を読み込む

-- imguiはフローティングウィンドウ内でのみ機能するため、最初に作成する必要があります。
demo_wnd = float_wnd_create(250, 150, 1, true)
float_wnd_set_title(demo_wnd, "imgui Demo") --ウィンドウのタイトル
float_wnd_set_imgui_builder(demo_wnd, "build_demo")

txtLine_1 = ""
txtLine_2 = ""
txtLine_3 = ""

-- imguiウインドウ内で実行するスクリプト -------------------------------------------------
function build_demo(wnd, x, y)
    local file = io.open(SCRIPT_DIRECTORY .. "read.txt", "r")
    for line in file:lines() do
        txtLine_1, txtLine_2, txtLine_3 = string.match(line, "(.-)%,(.-)%,(.+),") --(.+)は最後の読み込みにに使う。
        imgui.TextUnformatted(txtLine_1)
        imgui.TextUnformatted(txtLine_2)
        imgui.TextUnformatted(txtLine_3)

        local changed, newText_1 = imgui.InputText("Text-1", txtLine_1, 255) -- パラメーター:ラベル、現在のテキスト、許可される最大文字数
        if changed then
            txtLine_1 = newText_1
        end
        local changed, newText_2 = imgui.InputText("Text-2", txtLine_2, 255) -- パラメーター:ラベル、現在のテキスト、許可される最大文字数
        if changed then
            txtLine_2 = newText_2
        end
        local changed, newText_3 = imgui.InputText("Text-3", txtLine_3, 255) -- パラメーター:ラベル、現在のテキスト、許可される最大文字数
        if changed then
            txtLine_3 = newText_3
        end
    end
    file:close() -- 最後にf:closeでファイルを閉じる
end

別パターンの読み込み方法

こちらの方が簡単で理解しやすい。

書き出したファイルを読み込むことで、X-Planeを再起動しても表示を維持することができるようになる。
テキストファイルは改行で作成する。

15行〜20行で読み込んで、編集テキストを維持できるようになった。
と思ったが維持はできていない。リアルタイムに変更はできるが再起動すると内容はdata_2のテキストに変更されてしまう。つまり「line」は2行目のテキストを読み込んでいることになる。読み込みの方法が間違っていると思う。後で修正します。

if not SUPPORTS_FLOATING_WINDOWS then
    -- スクリプトが古いFlyWithLuaバージョンを停止しないようにするため
    logMsg("imgui not supported by your FlyWithLua version")
    return
end

local data_1 = ""--変数の数はio.openの数と必ず合わせる必要がある。
local data_2 = ""
local data_3 = ""
-- imguiはフローティングウィンドウ内でのみ機能するため、最初に作成する必要があります。
demo_wnd = float_wnd_create(200, 100, 1, true)
float_wnd_set_title(demo_wnd, "imgui TextEdit_Demo")
float_wnd_set_imgui_builder(demo_wnd, "build_demo")

--これによって編集テキストを維持できるようになった。
local backupfile = io.open(SCRIPT_DIRECTORY .. "read.txt", "r")
if backupfile ~= nil then --もしバックアップファイルが(nil)でない場合、つまり存在する場合。
    --以下の設定をするとテキストファイルにちゃんと記述されていないとウインドウ内のコンテンツが表示されなくる。
    bucontent = backupfile:lines() -- lines関数で行ごとに上から順番に読み込む
    data_1 = bucontent()           --1行目の読み込み
    data_2 = bucontent()           --2行目の読み込み
    data_3 = bucontent()

    backupfile:close()
end

--imguiでテキスト編集と編集したテキストを読み込み表示する関数
function build_demo(wnd, x, y)
    -- ユーザーがテキストを入力できるようにする。
    local changed, newText_1 = imgui.InputText("Text-1", data_1, 255) -- パラメーター:ラベル、現在のテキスト、許可される最大文字数
    if changed then
        data_1 = newText_1
    end
    local changed, newText_2 = imgui.InputText("Text-2", data_2, 255) -- パラメーター:ラベル、現在のテキスト、許可される最大文字数
    if changed then
        data_2 = newText_2
    end
    local changed, newText_3 = imgui.InputText("Text-3", data_3, 255) -- パラメーター:ラベル、現在のテキスト、許可される最大文字数
    if changed then
        data_3 = newText_3
    end

    local file = io.open(SCRIPT_DIRECTORY .. "read.txt", "w")
    file:write(data_1, "\n")
    file:write(data_2, "\n")
    file:write(data_3, "\n")
    file:close()
end

テストはしていないが、こんな方法もある

「if my_fp then」が余分に設定されている。

local my_fp = io.open(SCRIPT_DIRECTORY .. "hello.txt", "w")
if my_fp then
	my_fp:write("Hello world")
	my_fp:close()
end

日本語を読み込む

float_wnd_set_imgui_builderを使うと下のようには日本語を使えない。

このように日本語を使うには「float_wnd_set_ondraw()」を使う。テキスト読み込みは「draw_string」を使う必要がある。しかし、lineの行読み込みが1行になってしまう。何行かあるファイルを1行に重なって表示されてしまう。

fwl_wnd = float_wnd_create(250, 150, 1, true)
float_wnd_set_title(fwl_wnd, "imgui Demo")
float_wnd_set_ondraw(fwl_wnd, "on_draw")

function on_draw(fwl_wnd, x, y)
 
  local file = io.open(SCRIPT_DIRECTORY.."read.txt", "r")   -- read.txtの内容を読み込む。
  for line in file:lines() do   --ファイル内にあるだけの行を読み込む
    draw_string(x + 10, y + 10, line, "white")
  end
 
  file:close() -- 最後にf:closeでファイルを閉じる
end

\nのテキストが表示される問題

ファイルから改行テキストを表示したいのだが、\nの文字がそのまま表示され改行されない。

NSString* title = [NSString stringWithFormat:@"%@\n%@", onemb, twomb];
[myButton setTitle:title forState: UIControlStateNormal];
let firstLine = "first"
let secondLine = "second"
let button = UIButton()
button.setTitle(firstLine + "\n" + secondLine, for: .normal)

よくわからない。