Lua C ++表迭代

时间:2015-06-19 12:25:50

标签: c++ lua

我对lua_next如何真正起作用感到有些困惑。用户定义了一个表:

a={["a1"]=20,["a2"]=30}

我想用C ++代码打印此表:

inline int lua_print(lua_State* L)
{
wxString wxReturnStr=wxEmptyString;
wxString tempString=wxEmptyString;
int nargs = lua_gettop(L);

for (int i=1; i <= nargs; i++)
{
    int type = lua_type(L, i);
    switch (type)
    {

    case LUA_TNIL:
        break;

    case LUA_TBOOLEAN:
        tempString<<(lua_toboolean(L, i) ? "true" : "false");
        break;

    case LUA_TNUMBER:
        tempString<<lua_tonumber(L, i);
        break;

      case LUA_TSTRING:
          tempString<<lua_tostring(L, i);
        break;
      case LUA_TTABLE:
      {
          lua_pushnil(L);
          while(lua_next(L,-2))
          {
                const char* key=lua_tostring(L,-2);
                double val=lua_tonumber(L,-1);
                lua_pop(L,1);
                tempString<<key<<"="<<val<<"\t";
          }

          break;
      }

      default:
          tempString<<lua_typename(L, type);
        break;
    }

    wxReturnStr=wxReturnStr+tempString+"\n";
    tempString=wxEmptyString;

}

lua_pop(L,nargs);

当我从Lua打电话时,这段代码非常有效:

print(a) -- Works well

但是,想象一下我在Lua有一张桌子:

b={["b1"]=10, ["b2"]=15}

如果我将代码称为:

print(a,b) -- Twice prints only contents of b 

我对lua_next如何工作的理解如下图所示:enter image description here [Edition#1]

错误在哪里?

2 个答案:

答案 0 :(得分:2)

该错误位于lua_next(L, -2)行,因为-2指的是堆栈顶部减1,这里发生的是print的最后一个参数。

请改用lua_next(L, i)

Upd:在开发阶段移动代码时,Lua堆栈索引会浮动,因此一般的建议是在获取/推送/考虑值之后使用sml int t = lua_gettop(L)固定索引并使用{{1而不是t(虽然这个特定情况似乎是一个按键错误。)

答案 1 :(得分:0)

您在处理完表后忘记了lua_pop。

 lua_pushnil(L);
      while(lua_next(L,-2))
      {
            const char* key=lua_tostring(L,-2);
            double val=lua_tonumber(L,-1);
            lua_pop(L,1);
            tempString<<key<<"="<<val<<"\t";
      }
 lua_pop(L, 1); // THE FIX, pops the nil on the stack used to process the table

这意味着,额外的nil留在堆栈上,所以在第二次迭代中,

case LUA_TNIL:
   break;

只打印任何内容。

关于堆栈的图形表示。每个图像下的命令表示命令被调用后的状态。所以最后一张图片缺少堆栈上的[Key = a2]项目。