我试图迭代lua表但我不断收到此错误:
invalid key to 'next'
Run Code Online (Sandbox Code Playgroud)
我知道索引从-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");
}
Run Code Online (Sandbox Code Playgroud)
任何帮助,将不胜感激.
当我使用正索引时(只要我不从中删除1),这工作正常
编辑:我注意到,如果我单独留下项目的值,我就不会收到此错误.只有当我开始读取item的值时才会出现此错误.当我从表中获得值时,我调用另一个Lua函数,这可能会破坏lua_next吗?
fin*_*nnw 31
您需要注意两件事:
lua_next.luaL_checkstring将非字符串键转换为字符串(因为结果字符串不在表中,它将成为无效键.)通过传递luaL_checkstring密钥而不是原始密钥,可以轻松完成此操作.您的函数仅适用于负值index.你是正确的,index--;将确保index在按下键后仍然指向表,但只有当它index是负数(即相对于堆栈的顶部.)如果index是绝对或伪索引,那么这将导致它指向错误的项目.最简单的解决方法是将对表的另一个引用推送到堆栈顶部.
这是一个最小的C程序来演示:
#include <lauxlib.h>
#include <lua.h>
static void iterate_and_print(lua_State *L, int index);
int main(int ac, char **av)
{
lua_State *L = luaL_newstate();
luaL_openlibs(L);
// Create a table and put it on the top of the stack
luaL_loadstring(L, "return {one=1,[2]='two',three=3}");
lua_call(L, 0, 1);
iterate_and_print(L, -1);
return 0;
}
static void iterate_and_print(lua_State *L, int index)
{
// Push another reference to the table on top of the stack (so we know
// where it is, and this function can work for negative, positive and
// pseudo indices
lua_pushvalue(L, index);
// stack now contains: -1 => table
lua_pushnil(L);
// stack now contains: -1 => nil; -2 => table
while (lua_next(L, -2))
{
// stack now contains: -1 => value; -2 => key; -3 => table
// copy the key so that lua_tostring does not modify the original
lua_pushvalue(L, -2);
// stack now contains: -1 => key; -2 => value; -3 => key; -4 => table
const char *key = lua_tostring(L, -1);
const char *value = lua_tostring(L, -2);
printf("%s => %s\n", key, value);
// pop value + copy of key, leaving original key
lua_pop(L, 2);
// stack now contains: -1 => key; -2 => table
}
// stack now contains: -1 => table (when lua_next returns 0 it pops the key
// but does not push anything.)
// Pop table
lua_pop(L, 1);
// Stack is now the same as it was on entry to this function
}
Run Code Online (Sandbox Code Playgroud)
不要使用luaL_checkstring否定参数.请lua_tostring改用.
此外,确保在循环中调用函数后堆栈保持不变:lua_next期望堆栈顶部的前一个表键,以便它可以恢复遍历.
| 归档时间: |
|
| 查看次数: |
19057 次 |
| 最近记录: |