lua: 使用lua_next()遍历表
来源:互联网 发布:总决赛五项数据第一 编辑:程序博客网 时间:2024/06/08 18:34
// 进行下面步骤前先将 table 压入栈顶
int nIndex = lua_gettop( pLua ); // 取 table 索引值
lua_pushnil( pLua ); // nil 入栈作为初始 key
while( 0 != lua_next( pLua, nIndex ) )
{
// 现在栈顶(-1)是 value,-2 位置是对应的 key
// 这里可以判断 key 是什么并且对 value 进行各种处理
lua_pop( pLua, 1 ); // 弹出 value,让 key 留在栈顶
}
// 现在栈顶是 table
int nIndex = lua_gettop( pLua ); // 取 table 索引值
lua_pushnil( pLua ); // nil 入栈作为初始 key
while( 0 != lua_next( pLua, nIndex ) )
{
// 现在栈顶(-1)是 value,-2 位置是对应的 key
// 这里可以判断 key 是什么并且对 value 进行各种处理
lua_pop( pLua, 1 ); // 弹出 value,让 key 留在栈顶
}
// 现在栈顶是 table
lua_next() 这个函数的工作过程是:
1) 先从栈顶弹出一个 key
2) 从栈指定位置的 table 里取下一对 key-value,先将 key 入栈再将 value 入栈
3) 如果第 2 步成功则返回非 0 值,否则返回 0,并且不向栈中压入任何值
第 2 步中从 table 里取出所谓“下一对 key-value”是相对于第 1 步中弹出的 key 的。table 里第一对 key-value 的前面没有数据,所以先用 lua_pushnil() 压入一个 nil 充当初始 key。
注意开始的时候先用 lua_gettop() 取了一下 table 在栈中的正索引(前面说过了,在进行这个 lua_next() 过程之前先将 table 入栈,所以栈大小就是 table 的正索引),后面的 lua_next() 过程中不断的有元素出入栈,所以使用正索引来定位 table 比较方便。
到了 table 中已经没有 key-value 对时,lua_next() 先弹出最后一个 key,然后发现已经没有数据了会返回 0,while 循环结束。所以这个 lua_next() 过程结束以后 table 就又位于栈顶了。
在C里我们可以通过lua_gettable()或者lua_rawget()来获取表里元素值,但使用这两个接口的前提是你得知道key,它才能给你value. 当然对于顺序下标倒无所谓,但恰巧这次我用到的是关联数组,下标是无规则字符串.这时候如何遍历出表里元素就是个问题.
lua_next()就成了比较合适的选择.
上图对简单的表遍历做了介绍, 但事实上的情况是我返回了一个二维表,如果你了解了lua_next()的处理过程,那下面的代码看起来就没什么问题了.
t_idx = lua_gettop(L);
lua_pushnil(L);
while (lua_next(L, t_idx))
{
printf("============================\n");
it_idx = lua_gettop(L);
lua_pushnil(L);
while(lua_next(L, it_idx))
{
printf("%s\n", lua_tostring(L, -1));
lua_pop(L, 1);
}
lua_pop(L, 1);
}
本文仅起个抛砖引玉的作用, 实际上lua的栈逻辑基本就是这样.其他接口的调用方式也很类似.
1.参数压栈
2.call 函数
3.返回值位于栈顶
4.pop返回值
在C中遍历脚本中的table主要是通过lua c api lua_next来完成
具体实践如下:
代码如下:
#include <stdio.h>
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
int table_next(lua_State *L, int i,char **k, char **v)
{
if ( lua_next(L, i) !=0 )
{
*k = (char *)lua_tostring(L, -2);
*v = (char *)lua_tostring(L, -1);
lua_pop(L, 1);
return 1;
}
else
return 0;
}
int main(void)
{
lua_State *L;
int t_idx;
char *k= NULL;
char *v= NULL;
L = lua_open();
luaL_openlibs(L);
luaL_loadfile(L, "luatest.lua");
lua_pcall(L,0,0,0);
lua_getglobal(L,"testtab");
t_idx = lua_gettop(L);
lua_pushnil(L);
while( table_next(L,1,&k,&v) != 0)
{
fprintf(stderr, "k[%s]-v[%s]\n",k,v);
}
lua_close(L);
return 1;
}
脚本代码为:
[opensource@localhost ppt]$ cat luatest.lua
testtab={
MsgCode = "1",
Host = "127.0.0.1",
abc = "test",
id=100,
}
print("ok")
具体实践如下:
代码如下:
#include <stdio.h>
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
int table_next(lua_State *L, int i,char **k, char **v)
{
}
int main(void)
{
}
脚本代码为:
[opensource@localhost ppt]$ cat luatest.lua
testtab={
MsgCode = "1",
Host = "127.0.0.1",
abc = "test",
id=100,
}
print("ok")
0 0
- lua: 使用lua_next()遍历表
- 使用lua_next()遍历表
- 使用lua_next()遍历表
- lua表的遍历-易错点
- 【Lua】使用lfs遍历文件目录
- Lua中遍历表的方式
- c中遍历lua表结构
- c中遍历lua表结构
- c中遍历lua表结构
- C中的lua二维表遍历
- lua_next函数分析
- lua_next函数分析
- 【Lua】【3】Lua之使用表
- Lua遍历数组
- lua table 遍历
- Lua 中Table遍历
- lua遍历文件夹
- 遍历Lua全局环境变量
- 10-30-2 加班费,要不要?
- Visual Studio (VS)和Visual Assist X(VA)快捷键
- HDU3038 - How Many Answers Are Wrong(带权并查集)
- UITabBarController 标签栏控制器
- javascript的setTimeout()标题栏效果—闪烁文字
- lua: 使用lua_next()遍历表
- 百度Intern面试题之二叉树的网络传输及恢复--二叉树的文件存储和读取
- Heritrix总结及消重算法初探
- hdoj problem 1024Max Sum Plus Plus(动态规划&&DP问题)
- 【瞎搞】 HDU 1986 Encoding
- hdu 1863(畅通工程)(简单的并查集,模板)
- mysql 字符集设置查看
- poj3087--Shuffle'm Up(小模拟)
- 混合编译mexFunction