如何从C++循环遍历Lua表?

我正在尝试从Lua加载表格到C ++,但我无法正确处理它。 我第一次调用时还不错,但是在第二次调用lua_next时它崩溃了。 有什么想法吗?

Lua文件:

level = { 1, 2, 3, }

C ++文件-我首先执行了此操作:

lua_getglobal( L, "level" );
for( lua_pushnil( L ); lua_next( L, 1 ); lua_pop( L, -2 ) )
{
    if( lua_isnumber( L, -1 ) ) {
        int i = (int)lua_tonumber( L, -1 );
        //use number
    }
}
lua_pop( L, 1 );

然后我尝试从参考手册中使用:

lua_getglobal( L, "level" );
int t = 1;
lua_pushnil( L );
while( lua_next( L, t ) ) {
    printf( "%s - %s",
        lua_typename( L, lua_type( L, -2 ) ),
        lua_typename( L, lua_type( L, -1 ) ) );
    lua_pop( L, 1 );
}
lua_pop( L, 1 );

最后这个:

lua_getglobal( L, "level" );
lua_pushnil( L );

lua_next( L, 1 );
if( lua_isnumber( L, -1 ) ) {
    int i = (int)lua_tonumber( L, -1 );
    //use number fine
}
lua_pop( L, 1 );

lua_next( L, 1 ); //crashes

等等...

自然L是一个lua_State \ *,我正在初始化它并解析文件没问题。

原文链接 https://stackoverflow.com/questions/1438842

点赞
stackoverflow用户173099
stackoverflow用户173099

为什么在参考手册的版本中在末尾要多次执行'lua_pop(L,1)'操作?我可以看出这可能是一个问题,因为您正在将堆栈弹出超出堆栈深度的数量。

2009-09-17 13:51:23
stackoverflow用户112
stackoverflow用户112

当您调用lua_next时,第二个参数应该是表的索引。因为您只是用以下方式将表推到堆栈中

lua_getglobal(L,“level”);

调用之后,您的堆栈将如下所示

 -1:表“level”

(不是 +1,因为堆栈是向下读取的)。然后您调用

lua_pushnil(L);

所以您的堆栈是

 -1:键(nil-2:表“level”

您的表位于 -2,因此在调用 lua_next 时,应使用索引 -2。最后,在每次迭代之后,您的堆栈应该如下所示:

 -1:值
 -2:键
 -3:表“level”

因此,您想要读取值(在 -1),然后弹出它(因此只需弹出一次),然后调用 lua_next 来获得下一个键。因此,以下内容应有效:

lua_getglobal(L,“level”);
lua_pushnil(L);

while(lua_next(L,-2)){ // <== 这里是您的错误
     if(lua_isnumber(L,-1)){
        int i =(int)lua_tonumber(L,-1);
       //使用数字
    }
    lua_pop(L,1);
}
lua_pop(L,1);

根据您的第二次编辑进行编辑

由于您在去除外部内容时可以正常工作,但是当您将其添加回去时,最好的猜测是您以某种方式破坏了堆栈(C ++堆栈或lua堆栈)。特别是在操作lua状态时,请仔细查看指针。

2009-09-17 14:27:32
stackoverflow用户3362286
stackoverflow用户3362286

阅读 LUA 手册的 lua_next 可以发现,在直接使用 lua_tostring 时可能会出现问题,即你必须检查键的值,然后决定使用 lua_tostring 还是 lua_tonumber。所以你可以尝试使用以下代码:

   std::string key
   while(lua_next(L, -2) != 0){ // 在您的情况下,索引可能不是 -2,请检查

    // 使用“key”(在索引 -2 处)和“value”(在索引 -1 处)

    if (lua_type(L, -2)==LUA_TSTRING){ // 检查键是否为字符串
         // 您可以使用 key.assign(lua_tostring(L,-2));
    }
    else if (lua_type(L, -2)==LUA_TNUMBER){ // 或者如果它是一个数字
         // 这很可能是你的情况,因为你的表是这样的:{ 1, 2, 3, }
         // 不要声明字段 ID
         // 试试:
         // sprintf(buf,"%g",lua_tonumber(L,-2));
         // key.assign(buf);
    }
    else{
        // 做一些其他的事情
    }
    key.clear();
    lua_pop(L,1)
   }

希望它能有所帮助。

2014-02-27 20:54:49