完整C嵌套遍历lua5.3 table及重写print方法

 通过本章的学习,你可以掌握table的嵌套遍历,table内部无论嵌套多少层table都可以。
重写的print,你无论写多少个参数和多少个嵌套table都可以输出内容。

g_stringA 是笔者库中的一个字符串类, 直接使用下面的代码编译不通过,将g_stringA替换为别的类.

GxxLuaManager::GetStringFromLua 替换为 lua_tostring

看完下方代码,你应该可以理解嵌套遍历table的逻辑了。

void gxx_table_to_str( lua_State* L, int idx, g_stringA& res)
{
	if (!lua_istable(L, idx)) 
	{
		return;
	}
	else {
		res.AppendChar('{');

		// 将table拷贝到栈顶
		lua_pushvalue(L, idx);
		int it = lua_gettop(L);
		// 压入一个nil值,充当起始的key
		lua_pushnil(L);
		while (lua_next(L, it))
		{
			// 现在的栈:-1 => value; -2 => key; index => table
			// 拷贝一份 key 到栈顶,然后对它做 lua_tostring 就不会改变原始的 key 值了
			lua_pushvalue(L, -2);
			// 现在的栈:-1 => key; -2 => value; -3 => key; index => table
			if (!lua_istable(L, -2))
			{
				// 不是table就直接取出来就行
				const char* key = lua_tostring(L, -1);
				if(lua_isboolean(L, -2))
					res.AppendFormat("%s=%s,", key, lua_toboolean(L, -2) ? "true" : "false");
				else if(lua_isfunction(L, -2))
					res.AppendFormat("%s=%s,", key, "function");
				else
					res.AppendFormat("%s=%s,", key, GxxLuaManager::GetStringFromLua(L, -2));
			}
			else
			{
				const char* key = lua_tostring(L, -1);
				res.Append(key);
				res.AppendChar('=');
				// 此刻-2 => value
				gxx_table_to_str(L, -2, res);
				//lua_pop(L, 1);
				res.AppendChar(',');
			}
			
			// 弹出 value 和拷贝的 key,留下原始的 key 作为下一次 lua_next 的参数
			lua_pop(L, 2);
			// 现在的栈:-1 => key; index => table
		}
		// 现在的栈:index => table (最后 lua_next 返回 0 的时候它已经把上一次留下的 key 给弹出了)
		res.TrimRight(',');
		res.AppendChar('}');
		// 弹出上面被拷贝的table
		lua_pop(L, 1);
	}
}
int gxx_print( lua_State* L )
{
	int n = lua_gettop(L);
	g_stringA strPrint;
	for (int p = 1; p <= n; p++) 
	{
		if (lua_istable(L, p))
			gxx_table_to_str(L, p, strPrint);
		else if(lua_isboolean(L, p))
			strPrint.Append(lua_toboolean(L, p) ? "true" : "false");
		else if(lua_isfunction(L, p))
			strPrint.Append("function");
		else
			strPrint.Append(GxxLuaManager::GetStringFromLua(L, p));
		
		strPrint.AppendChar('\t');
	}
	strPrint.TrimRight('\t');

	TRACE(strPrint);
	TRACE("\r\n");
	return 0;
}

把print函数重新注册一下即可替换了

lua_register(m_L, "print", gxx_print);

执行一下lua脚本:

a = {
name = 'Guo',
age = '18',
fav = {'旅游','运动','美女'}

}

print (a)

输出结果为:

{name=Guo,age=18,fav={1=旅游,2=运动,3=美女}}

你可能感兴趣的:(lua5.3)