7

Luaでテーブルのテーブルを繰り返し処理して出力しようとしています:

  • 各テーブルのキー。
  • 各テーブルの各エントリのキーと値のペア。

コードは次のとおりです。

void print_table(lua_State *L)
{
    lua_pushnil(L);
    while(lua_next(L, -2) != 0) {
    const char *key = lua_tostring(L, -2);
            if(lua_isstring(L, -1))
                printf("%s = %s", key, lua_tostring(L, -1));
            else if(lua_isnumber(L, -1))
                printf("%s = %d", key, lua_tonumber(L, -1));
            else if(lua_istable(L, -1)) {
                printf("%s", key);
                PrintTable(L);
            }
            lua_pop(L, 1);
        }
    }
}

そして、これは私が出力しようとしているテーブルの1つの例です:

s = {
        p = {
            n = "D",
            g = "1",
        },
        d = {
            l = "N",
            p = "N",
            u = "O",
            po = 100,
        },
        e = {
            {
                n = "B",
                l = "P",
                p = "P",
                u = "P",
                po = "P",
                pa = {
                    v = "4",
                    a = "U",
                    f = {
                        { name = "U", type = "U" },
                        { name = "A", type = "I" },
                        { name = "A", type = "I" },
                        { name = "P", type = "U" },
                        { name = "P", type = "U" },
                        { name = "P", type = "I" },
                        { name = "T", type = "U" },
                        { name = "D", type = "U" },
                        { name = "D", type = "I" },
                        { name = "S", type = "I" },
                        { name = "C", type = "U" },
                        { name = "G", type = "U" },
                        { name = "C", type = "F" },
                        { name = "C", type = "U" },
                    },
                },
                c = {
                    v = "1",
                    a = "",
                    f = {
                        { name = "B", type = "U" },
                        { name = "E", type = "F" },
                    },
                },
            },
        },
    }

関数は次の行でクラッシュします。

while(lua_next(L, -2) != 0)

無効なインデックスが原因です。クラッシュを引き起こすスクリプトの行は次のとおりです。

{ name = "B", type = "U" },

私は Lua のスタックにあまり精通していないことを認めなければなりません。同様の回答を検索しようとしましたが、何も見つかりませんでした。私が間違っていることを知っている人はいますか?

ありがとう!

誰かが興味を持っている場合に備えて、作業バージョンを追加しました:

void print_table(lua_State *L)
    {
        if ((lua_type(L, -2) == LUA_TSTRING))
            printf("%s", lua_tostring(L, -2));

        lua_pushnil(L);
        while(lua_next(L, -2) != 0) {
            if(lua_isstring(L, -1))
                printf("%s = %s", lua_tostring(L, -2), lua_tostring(L, -1));
            else if(lua_isnumber(L, -1))
                printf("%s = %d", lua_tostring(L, -2), lua_tonumber(L, -1));
            else if(lua_istable(L, -1)) {
                print_table(L);
            }
            lua_pop(L, 1);
        }
    }
4

1 に答える 1

9
f = {
    { name = "B", type = "U" },
    { name = "E", type = "F" },
}

以下と同等です。

f = {
    [1] = { name = "B", type = "U" },
    [2] = { name = "E", type = "F" },
}

キーを呼び出すlua_tostringと、Lua は数値インデックスを文字列に変更します。

const char *key = lua_tostring(L, -2);

lua_tostring使用lua_tolstringし、マニュアルから:

値が数値の場合、 lua_tolstring はスタック内の実際の値も文字列に変更します。(この変更により、lua_tolstring がテーブル走査中にキーに適用されると lua_next が混乱します。)

スタック値を文字列に変換できるかどうかしか分からないlua_typeため、キーが本当に文字列かどうかを確認するために使用することをお勧めします。lua_isstringキーのコピーをプッシュして、コピーを呼び出すこともできlua_tostringます。

于 2015-03-26T20:49:34.470 に答える