我更喜欢char*
而不是std::string
,所以我写了一个组合char指针的函数。我创建了一个新项目并进行了测试。它工作正常。但是当我尝试在一个更大的GUI项目中使用它时,我的程序崩溃了。
这是一个示例(工作)代码:
#include <Windows.h>
#include <vector>
char *StringJoin(const char *String, const char* ...)
{
va_list ArgList;
va_start(ArgList, String);
std::vector<const char *> StringData;
std::vector<unsigned int> StringLen;
StringData.push_back(String);
unsigned int SingleLength = strlen(String);
StringLen.push_back(SingleLength);
unsigned int TotalLength = SingleLength;
while (1)
{
const char* Val = va_arg(ArgList, const char*);
if (!Val)
break;
StringData.push_back(Val);
SingleLength = strlen(Val);
StringLen.push_back(SingleLength); // In larger projects it crashes here
TotalLength += SingleLength;
}
va_end(ArgList);
char *NewString = new char[TotalLength + 1];
unsigned int VectorSize = StringData.size();
unsigned int NewLength = 0;
for (unsigned int Element = 0; Element < VectorSize; Element++)
{
memcpy(NewString + NewLength, StringData[Element], StringLen[Element]);
NewLength += StringLen[Element];
}
NewString[TotalLength] = '\0';
StringData.clear();
StringLen.clear();
return NewString;
}
int main(void)
{
char* New = StringJoin("Does ", "it ", "works ", "for ", "you ", "?");
printf("%s\n", New);
system("PAUSE");
return 1;
}
我的代码安全稳定吗?
答案 0 :(得分:2)
您无法使用!Val
条件:
const char* Val = va_arg(ArgList, const char*);
if (!Val)
break;
使用变量参数列表时,您需要知道完全已传递了多少参数,或者(更新)何时停止处理参数,例如使用NULL
/ nullptr
(或任何其他)sentinel.
答案 1 :(得分:0)
如果你的编译器支持它,你肯定应该使用可变参数模板。
以下非常简单的函数接受任意数量的字符串并在循环中连接它。它支持std::string
和char*
参数(甚至是混合):
template<class ...Strings>
std::string StringJoin(Strings ...strings) {
std::string joined;
for (auto s : { strings... })
joined += s;
return joined;
}
现在,如果您希望结果为char*
,则需要考虑分配内存的位置以及解除分配的位置,即您需要手动管理内存。除非你使用智能指针:
template<class ...Strings>
std::unique_ptr<char[]> StringJoin(Strings ...strings) {
std::string joined;
for (auto s : { strings... })
joined += s;
std::unique_ptr<char[]> buf(new char[joined.size() + 1]);
memcpy(buf.get(), joined.data(), joined.size());
buf[joined.size()] = '\0';
return buf;
}