Итерирование таблицы таблиц с помощью API Lua C

Я пытаюсь перебрать таблицу таблиц в Lua и выводить:

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

Вот код:

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

     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 и из руководства :

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

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