您的位置:首页 > 编程语言 > C语言/C++

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

2011-03-03 00:00 507 查看
近日做脚本接口时遇到一个变参的传入接口,因为我们游戏中的脚本系统是自定义的,这个接口的参数因为是可变,所以将参数读进来存入一个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;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#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/C++