字符串附加功能不起作用

String appending function doesn't work

我试图创建一个可以轻松附加两个字符串的函数。源字符串必须事先动态分配。我使用了我的知识,但这导致了 ub 和任何类型的泄漏。


void strapp (char *source_offset, int position, char *appendage)
{
    size_t appendage_size = strlen(appendage);

    source_offset = realloc(source_offset, strlen(source_offset) + appendage_size);
    sprintf( &source_offset[position], "%s%s", appendage, source_offset + (position + appendage_size) );
}

我做错了什么?

size_t appendage_size = strlen(appendage) + 1; /* To hold a [=10=] character */

分配的新数组应该能够容纳每个字符串中的两个空字符

strlen(string) + 1

source_offset + (position + appendage_size) 有点奇怪。您似乎试图将第二个字符串与第一个字符串的子字符串进行连接,将结果复制到第一个字符串中。

source_offset + (position + appendage_size) 是从偏移量 position+appendage_size 开始的源字符串的后缀,这是无意义的,因为它超过了源字符串的末尾...

也许你想要这样的东西? 如果要连接两个字符串,则以下内容是正确的:

size_t appendage_size = strlen(appendage);
source_offset = realloc(source_offset, position + appendage_size + 1);
sprintf( &source_offset[position], "%s", appendage );

position 开始将 appendage 附加到 source_offset

现在如果你想在中间插入 appendage 这可能有点棘手:

size_t appendage_size = strlen(appendage);
char *result = malloc(strlen(source_offset) + appendage_size + 1);
char cut = source_offset[position];
source_offset[position] = '[=11=]';
sprintf( result, "%s%s%c%s", source_offset,appendage,cut,source_offset+position+1);
// do hat you want with result

注意realloc可能会改变初始内存的基地址,所以你不能这样做,因为参数值source_offset只会在本地改变。

如果你想修复你的功能,试试这个:

void strapp (char **source_offset, int position, char *appendage)
{
    size_t appendage_size = strlen(appendage);

    *source_offset = (char*)realloc(*source_offset, strlen(*source_offset) + appendage_size);
    sprintf( *source_offset + position, "%s%s", appendage, *source_offset + (position + appendage_size) );
}

并称其为 strapp(&str, 10, "INSERTION"); // &str - pointer to pointer

问题如下:当您将指针发送给函数时,您可以更改此指针指向的数据,但不能更改指针,因此在函数内部进行的内存分配不会更改初始字符串的地址。

实际上,您的 coes 不会将字符串 B 附加到字符串 A,它会将字符串 B 与字符串 A 一起附加到字符串 A 的位置 n,并且字符串 A 的一些内存偏移

char *
strapp(char *dest, const char *src)
{
    size_t i,j;
    for (i = 0; dest[i] != '[=10=]'; i++)
        ;
    for (j = 0; src[j] != '[=10=]'; j++)
        dest[i+j] = src[j];
    dest[i+j] = '[=10=]';
    return dest;
}

上面的代码将字符串 B 附加到字符串 A 和 returns 指向字符串 A 的指针;

char* strapp (char *source_offset, const char *appendage, int position)
{
    char* temp = NULL:
    size_t appendage_size = strlen(appendage);
    if (( temp = realloc(source_offset, strlen(source_offset) + appendage_size + 1)) == NULL )
        return NULL;
    else
        source_offset = temp;
    sprintf( &source_offset[position], "%s", appendage);
    return source_offset;
}

因为我被要求提供函数使用示例和输出。我将此代码转换为可编译为 mingw 的代码,它按预期工作。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

void strapp (char *source_offset, int position, char *appendage)
{
    size_t appendage_size = strlen(appendage) + 1;

    source_offset = realloc(source_offset, strlen(source_offset) + appendage_size);
    sprintf( &source_offset[position], "%s%s", appendage, source_offset + (position + appendage_size) );
}

int main(void)
{
    char *str1 = malloc(11 + 1);

    sprintf(str1, "Hello World");

    strapp(str1, 4, " Horrible ");

    printf(str1);
    free(str1);

    return 0;
}

输出:Hell Horrible

部分修复了我在调查时发现的问题。 如果我像这样将子字符串添加到源字符串的位置:

sprintf(&source[4], "new");

源字符串将由 "new" 终止,字符串的其余部分将不会显示。 但是如果我声明子字符串 "new" 并使用 memcpy(&str1[4], appendage, 3); 它完成了工作。


好了,这是工作函数:

void strapp (char *source_offset, int position, char *appendage)
{
    size_t appendage_size = strlen(appendage) + 1;
    char copy[strlen(source_offset) + 1];

    strcpy(copy, source_offset);

    source_offset = realloc(source_offset, strlen(source_offset) + appendage_size);
    memcpy(&source_offset[position], appendage, strlen(appendage));
    sprintf(&source_offset[position + strlen(appendage)], &copy[position]);
}