Char* combining

Char* combining

本文关键字:combining Char      更新时间:2023-10-16

我更喜欢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] = '';
    StringData.clear();
    StringLen.clear();
    return NewString;
}
int main(void)
{
    char* New = StringJoin("Does ", "it ", "works ", "for ", "you ", "?");
    printf("%sn", New);
    system("PAUSE");
    return 1;
}

我的代码安全稳定吗?

不能使用!Val条件:

const char* Val = va_arg(ArgList, const char*);
if (!Val)
    break;

当使用变量参数列表时,您需要确切地知道传递了多少参数,或者(更新)何时停止处理参数,例如使用NULL/nullptr(或任何其他)哨兵。

如果你的编译器支持可变模板,你肯定应该使用它。

下面这个非常简单的函数接受任意数量的字符串,并将它们连接在一个循环中。它同时支持std::stringchar*作为参数(甚至混合使用):

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()] = '';
    return buf;
}

现场演示