1. 程式人生 > >【C/C++】sprintf中如何將容器作為可變引數列表傳入

【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]