问题
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