使用 Lua C API 迭代 table 的 table 秒
Iterating over table of tables with the Lua C API
我正在尝试迭代 Lua 中的 table 个 table 并输出:
- 每个table的键。
- 每个table中每个条目的键/值对。
代码如下:
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);
}
}
}
这是我尝试输出的 table 之一的示例:
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);
}
}
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
并从 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.)
最好使用 lua_type
检查键是否真的是字符串,因为 lua_isstring
只会告诉你堆栈值是否可以转换为字符串。您还可以推送密钥的副本并在副本上调用 lua_tostring
。
我正在尝试迭代 Lua 中的 table 个 table 并输出:
- 每个table的键。
- 每个table中每个条目的键/值对。
代码如下:
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);
}
}
}
这是我尝试输出的 table 之一的示例:
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);
}
}
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
并从 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.)
最好使用 lua_type
检查键是否真的是字符串,因为 lua_isstring
只会告诉你堆栈值是否可以转换为字符串。您还可以推送密钥的副本并在副本上调用 lua_tostring
。