2015-03-26 3 views
4

Я пытаюсь перебрать таблицу таблиц в Lua и выход:Итерация над столом таблиц с API Lua C

  • Ключ каждой таблицы.
  • Пара ключей/значений каждой записи в каждой таблице.

Вот код:

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); 
     } 
    } 

ответ

4
f = { 
    { name = "B", type = "U" }, 
    { name = "E", type = "F" }, 
} 

эквивалентно:

f = { 
    [1] = { name = "B", type = "U" }, 
    [2] = { name = "E", type = "F" }, 
} 

При вызове lua_tostring на клавишной Lua изменяет числовой индекс в строку.

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

lua_tostring использует lua_tolstring и от manual:

Если значение является числом, то lua_tolstring также изменяет фактическое значение в стеке на строку. (Это изменение путает lua_next когда lua_tolstring применяется к ключам во время таблицы обходом.)

Лучше использовать lua_type, чтобы проверить, если ключ действительно является строкой, так как lua_isstring будет только сказать вам, если значение стека может быть преобразован в строка. Вы также можете нажать копию ключа и набрать lua_tostring на копии.

+0

Отличный ответ, спасибо огромное! – lamma