Iterating over table of tables with the Lua C API

喜你入骨 提交于 2019-12-30 07:07:08

问题


I'm trying to iterate over a table of tables in Lua and output:

  • The key of each table.
  • The key / value pair of each entry in each table.

Here is the code:

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);
        }
    }
}

And here is an example of one of a table I'm trying to output:

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" },
                    },
                },
            },
        },
    }

The function crashes in the line:

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

due to an invalid index. The line of script that causes the crash is:

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

I have to admit I'm not massively familiar with the stack in Lua, I've tried searching for similar answers and was unable to find any. Anyone know what I'm doing wrong?

Thanks!

Added working version in case anyone is interested:

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);
        }
    }

回答1:


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

Is equivalent to:

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

When you call lua_tostring on the key Lua changes the numeric index to a string.

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

lua_tostring uses lua_tolstring and from the manual:

If the value is a number, then lua_tolstring also changes the actual value in the stack to a string. (This change confuses lua_next when lua_tolstring is applied to keys during a table traversal.)

Better to use lua_type to check if the key really is a string since lua_isstring will only tell you if the stack value can be converted into a string. You could also push a copy of the key and call lua_tostring on the copy.



来源:https://stackoverflow.com/questions/29287988/iterating-over-table-of-tables-with-the-lua-c-api

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!