【C/C++】sprintf中如何将容器作为可变参数列表传入

近日做脚本接口时遇到一个变参的传入接口,因为我们游戏中的脚本系统是自定义的,这个接口的参数因为是可变,所以将参数读进来存入一个Vector容器中,然后利用Sprintf格式化之后发送给客户端做逻辑,以前的做法就是switch…case…这个容器中元素的个数,然后sprintf( szBuff, nBuffSize – 1, szFormat, vtVar[0], vtVar[1], ……),而如今要变参,这样的方法肯定是行不通了,想了一下截取字符串的方法存入,尝试了一下,是可以行得通的,与大家分享一下代码。

希望大家有更好的方法可以交流,谢谢!
[c]
#include <stdio.h>
#include <iostream>
#include <vector>
using namespace std;

void ScriptSprintf( char* szBuf, int nBufSize, const char* szText,
const std::vector<std::string>& vtVar )
{
string strTemp(szText);
const char* szSpn = "%s";
int nBeginPos = 0;
int nEndPos = 0;
string strSub;

if ( vtVar.empty() )
{
strncpy_s( szBuf, nBufSize – 1, szText, nBufSize – 1);
return;
}

std::vector<string>::const_iterator iterBegin = vtVar.begin();
std::vector<string>::const_iterator iterEnd = vtVar.end();
for ( ; iterBegin != iterEnd; ++iterBegin )
{// 容器元素的操作建议还是使用迭代器,因为vtVar为const,所以迭代器为const_iterator
strSub.clear();
nEndPos = strTemp.find(szSpn);
if ( nEndPos != strTemp.length() ) // 找到了%s
{
strSub = strTemp.substr(nBeginPos, nEndPos – nBeginPos + 2); // 截取前面的字串XXX%s
strTemp = strTemp.substr(nEndPos + 2, strTemp.length() – nEndPos – 2); // 缩短strTemp
// 特别注意此处的strlen,他可以将字串往后加
sprintf( szBuf + strlen(szBuf), strSub.c_str(), iterBegin->c_str() ); // 按格式存入
}
}

if ( !strTemp.empty() )
{// 如果为XXX%sYYY,%s以前的字串前面已经处理过,剩余的字串还需要拼起来
strncpy( szBuf, strTemp.c_str(), strTemp.length() );
}
}

int _tmain(int argc, _TCHAR* argv[])
{
char szBuf[1024] = {0};
const char* szText = "AAA%sBBB%sCCC%sDDD%sEEE%s";
std::vector<std::string> vtVar;
vtVar.push_back("1");
vtVar.push_back("2");
vtVar.push_back("3");
vtVar.push_back("4");
vtVar.push_back("5");
ScriptSprintf(szBuf, 1023, szText, vtVar);
cout<<szBuf<<endl;

system("pause");
return 0;
}
[/c]


NickYang

NickYang

无知一码农,现居住于上海,从事游戏服务器端开发
http://www.cppfans.org

发表评论

电子邮件地址不会被公开。 必填项已用*标注