使用Lua C API迭代表的表

我正在尝试迭代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); } } } 

这是我正在尝试输出的一个表的示例:

 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上调用lua_tostring时,将数字索引更改为字符串。

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

lua_tostring使用lua_tolstring并从手册中 :

如果值是数字,则lua_tolstring还将堆栈中的实际值更改为字符串。 (当在表遍历期间将lua_tolstring应用于键时,此更改会混淆lua_next。)

最好使用lua_type来检查密钥是否真的是一个字符串,因为lua_isstring只会告诉你堆栈值是否可以转换成字符串。 您也可以推送密钥的副本并在副本上调用lua_tostring