我尝试迭代lua表,但一直收到以下错误:
invalid key to 'next'
我知道index从-8开始,我知道那里有一个表,因为它得到了表中的第一个(也是唯一的)值,但是,它试图再次循环,即使我知道表中只有一个字符串。
if (lua_istable(L, index))
{
lua_pushnil(L);
// This is needed for it to even get the first value
index--;
while (lua_next(L, index) != 0)
{
const char *item = luaL_checkstring(L, -1);
lua_pop(L, 1);
printf("%s\n", item);
}
}
else
{
luaL_typerror(L, index, "string table");
}
任何帮助都将不胜感激。
- 当我使用正索引时,这很有效(只要我不从它中删除1)*
**编辑:**我注意到如果我不去处理item的值,我不会得到这个错误。只有当我开始阅读item的值时,我才会得到这个错误。当我从表中得到值时,我调用了另一个Lua函数,这会不会破坏了lua_next?
4条答案
按热度按时间laik7k3q1#
有两件事你需要注意:
lua_next
之前,确保原始密钥保留在堆栈上。luaL_checkstring
会将非字符串密钥转换为字符串(由于结果字符串不在表中,因此它将成为无效密钥)。通过向luaL_checkstring
传递密钥的副本而不是原始密钥,可以最容易地实现这一点。您的函数只对
index
的负值有效。您正确地认为index--;
将确保index
在按下键后仍指向表。但仅当index
为负时(即相对于栈顶。)如果index
是绝对或伪索引,则这将导致它指向错误的项。最简单的解决方法是将对表的另一个引用推送到堆栈的顶部。下面是一个最小的C程序来演示:
mwecs4sa2#
不要使用带负参数的
luaL_checkstring
。请改用lua_tostring
。此外,确保在循环中调用函数后堆栈保持不变:
lua_next
期望堆栈顶部的前一个表键,以便它可以继续遍历。ehxuflar3#
来自手册:
将给定可接受索引处的Lua值转换为C字符串。如果len不为NULL,则还将字符串长度设置为 *len。Lua值必须是字符串或数字;如果值是一个数字,那么lua_tolstring也会将堆栈中的实际值更改为字符串。(当lua_tolstring在表遍历期间应用于键时,此更改会混淆lua_next。)
luaL_checkstring
调用lua_tolstring
。lskq00tm4#
另请参见
lua_next
文档中的示例,摘录如下:int lua_next (lua_State *L, int index);
从堆栈中弹出一个键,并从给定索引处的表中压入一个键值对(给定键之后的“下一个”键值对)。如果表中没有更多的元素,则
lua_next
返回0(不压入任何内容)。典型的遍历如下所示:
在遍历表时,不要直接在键上调用
lua_tolstring
,除非你知道键实际上是一个字符串,回想一下lua_tolstring
可能会改变给定索引的值;这混淆了对lua_next
的下一个调用。有关在遍历过程中修改表的注意事项,请参见函数
next
。