代码之家  ›  专栏  ›  技术社区  ›  Zack Lee

如何使用重新定义的print函数打印Lua表?

  •  2
  • Zack Lee  · 技术社区  · 6 年前

    我学会了如何重新定义Lua的 print() 在C++中从这个帖子。( https://stackoverflow.com/a/4514193/5224286 )

    post.. )

    int l_my_print(lua_State *L)
    {
        int nargs = lua_gettop(L);
        for (int i = 1; i <= nargs; ++i)
        {
            if (lua_isnil(L, i))
                poststring("nil");
            else if (lua_isboolean(L, i))
                lua_toboolean(L, i) ? poststring("true") : poststring("false");
            else if (lua_isnumber(L, i))
                postfloat(static_cast<t_float>(lua_tonumber(L, i)));
            else if (lua_isstring(L, i))
                poststring(lua_tostring(L, i));
            else if (lua_istable(L, i))
                poststring("table: "); //how to print like Lua's built-in print()?
        }
        endpost();
        return 0;
    }
    

    这段代码工作正常,除非我打印表格。(它只是打印出来的 table:

    我想知道如何像Lua那样打印表格 打印() 作品。

    例如,当我在Lua中运行以下代码时:(在重定义之前)

    print({1,2,3});
    

    我得到这样的结果:(这似乎是不断变化的)

    table: 0x23b8660
    

    l_my_print() 所以它可以像Lua一样工作 打印()

    2 回复  |  直到 6 年前
        1
  •  1
  •   Henri Menke    6 年前

    只是使用 luaL_tolstring 得到任何东西的字符串表示。这也尊重 __tostring std::string_view

    #include <iostream>
    #include <string_view>
    
    #include <lua.hpp>
    
    void poststring(std::string_view sv) { std::cout << sv << '\n'; }
    
    void endpost() { std::cout << "---\n"; }
    
    int l_my_print(lua_State *L) {
        int nargs = lua_gettop(L);
        for (int i = 1; i <= nargs; ++i) {
            poststring(luaL_tolstring(L, i, nullptr));
            lua_pop(L, 1); // remove the string
        }
        endpost();
        return 0;
    }
    
    int main() {
        lua_State *L = luaL_newstate();
        luaL_openlibs(L);
    
        lua_pushcfunction(L, l_my_print);
        lua_setglobal(L, "my_print");
    
        int i = 0;
        lua_pushlightuserdata(L, &i);
        lua_setglobal(L, "udata");
    
        luaL_dostring(L, "my_print(1, 3.14, \"Hello World\")\n"
                         "my_print(false, udata, {})\n");
    
        lua_close(L);
    }
    

    调用示例:

    $ clang++ -Wall -Wextra -Wpedantic -std=c++17 -I/usr/include/lua5.3 test.cpp -llua5.3
    $ ./a.out 
    1
    3.14
    Hello World
    ---
    false
    userdata: 0x7fff4685993c
    table: 0x883300
    ---
    
        2
  •  0
  •   G. B.    6 年前

        --Produces a compact, uncluttered representation of a table. Mutual recursion is employed
        --source: http://lua-users.org/wiki/TableUtils
        function table.tostring( tbl )
          local result, done = {}, {}
          for k, v in ipairs( tbl ) do
            table.insert( result, table.val_to_str( v ) )
            done[ k ] = true
          end
          for k, v in pairs( tbl ) do
            if not done[ k ] then
              table.insert( result,
                table.key_to_str( k ) .. "=" .. table.val_to_str( v ) )
            end
          end
          return "{" .. table.concat( result, "," ) .. "}"
        end