C字符串附加

时间:2011-05-18 16:56:52

标签: c string append

我正在寻找一种附加多个字符串的有效方法 它的工作方式是C ++ std :: string :: append或JAVA StringBuffer.append。

我编写了一个实际重新分配前一个源指针并执行strcat的函数。

我认为这不是一种有效的方法,因为编译器可以实现这个free和malloc。

我能想到的其他方式(如std :: vector)是批量分配内存(例如1KB)并执行strcpy。在这种情况下,每个追加调用将检查所需的总分配是否大于(1200字节)批量分配的数量,重新分配到2KB。但在这种情况下会浪费一些内存。

我正在寻找上述之间的平衡,但偏好是表现。

还有哪些方法可行。请建议。

4 个答案:

答案 0 :(得分:4)

我会将每个字符串添加到列表中,并将每个新字符串的长度添加到运行总计中。然后,当你完成后,为该总数分配空间,遍历列表并将每个字符串strcpy到新分配的空间。

答案 1 :(得分:2)

经典方法是每次缓冲时将缓冲区加倍。

从一个“合理的”缓冲区开始,所以你不需要对大小为1,2,4,8,1的realloc()进行操作,这些大小会被大量的字符串击中

从1024字节开始意味着如果你点击2048就会有一个realloc(),如果你达到4096就会有一秒{2},依此类推。如果猖獗的内存消耗让你感到害怕,那么一旦达到适当大的增长率(如65536字节或其他),就会限制增长率,这取决于你的数据和内存容忍度。

另外请确保缓冲当前长度,这样您就可以strcpy()执行{{1}}而无需先走动字符串来查找长度。

答案 2 :(得分:0)

连接字符串的示例函数

void
addToBuffer(char **content, char *buf) {
    int textlen, oldtextlen;
    textlen =  strlen(buf);
    if (*content == NULL)
        oldtextlen = 0;
    else
        oldtextlen = strlen(*content);
    *content = (char *) realloc( (void *) *content, (sizeof(char)) * (oldtextlen+textlen+1));
    if ( oldtextlen != 0 ) {
        strncpy(*content + oldtextlen, buf, textlen + 1);
    } else {
        strncpy(*content, buf, textlen + 1);
    }
}

int main(void) {
    char *content = NULL;
    addToBuffer(&content, "test");
    addToBuffer(&content, "test1");
}

答案 3 :(得分:0)

我会做这样的事情:

typedef struct Stringbuffer {
    int capacity;     /* Maximum capacity. */
    int length;       /* Current length (excluding null terminator). */
    char* characters; /* Pointer to characters. */
} Stringbuffer;

BOOL StringBuffer_init(Stringbuffer* buffer) {
    buffer->capacity = 0;
    buffer->length = 0;
    buffer->characters = NULL;
}

void StringBuffer_del(Stringbuffer* buffer) {
    if (!buffer)
        return;

    free(buffer->characters);

    buffer->capacity = 0;
    buffer->length = 0;
    buffer->characters = NULL;
}

BOOL StringBuffer_add(Stringbuffer* buffer, char* string) {
    int len;
    int new_length;

    if (!buffer)
        return FALSE;

    len = string ? strlen(string) : 0;

    if (len == 0)
        return TRUE;

    new_length = buffer->length + len;

    if (new_length >= new_capacity) {
        int new_capacity;

        new_capacity = buffer->capacity;

        if (new_capacity == 0)
            new_capacity = 16;

        while (new_length >= new_capacity)
            new_capacity *= 2;

        new_characters = (char*)realloc(buffer->characters, new_capacity);
        if (!new_characters)
            return FALSE;

        buffer->capacity = new_capacity;
        buffer->characters = new_characters;
    }

    memmove(buffer->characters + buffer->length, string, len);
    buffer->length = new_length;
    buffer->characters[buffer->length] = '\0';

    return TRUE;
}