将字符串插入另一个字符串

问题描述 投票:0回答:6

好的,所以我有一个 char stringA 和 char stringB,我希望能够将 stringB 插入到 stringA 的 x 点。

char *stringA = "abcdef";
char *stringB = "123";

产品为

"ab123cdef"

有人知道该怎么做吗?预先感谢

c
6个回答
16
投票
char * strA = "Blahblahblah", * strB = "123", strC[50];
int x = 4;
strncpy(strC, strA, x);
strC[x] = '\0';
strcat(strC, strB);
strcat(strC, strA + x);
printf("%s\n", strC);

说明:

  1. 您声明要连接的两个字符串,以及要放入它们的第三个字符串。
  2. 您声明一个整数来告诉程序您希望在第一个字符串中插入多少个字符。
  3. strncpy 函数将前 x 个字符复制到 strC 中。您必须在末尾添加空('')字符,否则您可能会得到垃圾。
  4. Strcat 复制第二个字符串。
  5. 另一个 strcat 复制第一个字符串的剩余部分 (strA + x)。

希望有帮助。

备注:记住让 strC 足够长以包含 strA 和 strC,否则会产生分段错误。您可以通过将字符串声明为数组来完成此操作,就像我的示例中一样。


9
投票

stringA 和 stringB 都是指针 - 它们包含内存块的起始地址。 它们指向的内存分别包含连续的字符串:“abcdef”和“123”。 由于字符串是连续的块内存(意味着给定字符的内存位置是前一个字符之后的一个字节),因此如果不先移动一些字符,则无法将更多字符插入到字符串中间。 在你的情况下,你甚至不能真正做到这一点,因为为每个字符串分配的内存量足够大,足以容纳该字符串(忽略填充)。

您要做的是将字符串复制到您为此目的分配的另一个内存块,然后复制它们,以便第二个字符串在第一个字符串中以 x 个字符开头。

其他几个 SO 用户已经发布了代码解决方案,但我认为您应该尝试自己找到确切的解决方案(希望我对正在发生的事情的高级解释会有所帮助)。


3
投票

这里有一个更通用的解决方案。

注意

destination
内存中必须有足够的空间来添加种子(例如,大小大于
strlen(seed)+strlen(destination)
的堆分配数组)。所以,关于这个问题,你必须创建一个更大的数组。

/* 
    destination: a NULL terminated string
    pos: where insert seed
    seed: a NULL terminated string
*/
void insertString(char* destination, int pos, char* seed)
{
    char * strC;

    strC = (char*)malloc(strlen(destination)+strlen(seed)+1);
    strncpy(strC,destination,pos);
    strC[pos] = '\0';
    strcat(strC,seed);
    strcat(strC,destination+pos);
    strcpy(destination,strC);
    free(strC);
}

2
投票
int insert_pos = 5;
int product_length = strlen(stringA) + strlen(stringB) + 1;
char* product = (char*)malloc(product_length);
strncpy(product, stringA, insert_pos);
product[insert_pos] = '\0';
strcat(product, stringB);
strcat(product, stringA + insert_pos);
...
free(product);

0
投票

这里有很多答案。 然而,大多数确实依赖于

strcat()
,而不是使用高效为分配计算的长度,没有一个是安全,也没有一个提供就地插入的解决方案。

情况1:你想分配一个新的字符串

只需将不同的字符串组件复制到其目标地址,避免使用

strcat()
迭代它们,考虑到一旦它们的长度足够就进行计算。 请记住,malloc() 可能会返回 NULL:

char* strmake_insert (const char *str, size_t pos, const char *insertstr) 
{
    size_t sl = strlen(str), il = strlen(insertstr);
    
    char *newstr=malloc(sl+il+1);
    if (newstr) {
        memcpy (newstr, str, pos);
        memcpy (newstr+pos, insertstr, il);
        memcpy (newstr+pos+il, str+pos, sl-pos);   
    }
    return newstr; 
}  

使用示例:

char *s = strmake_insert("abcdef", 3, "123"); printf("新字符串:%s “,s); 免费;

我将把这个版本强化为安全版本作为练习。

情况 2:您想在原始字符串中就地插入

我们假设缓冲区中有足够的空间分配给原始字符串。 使用

memcpy()
可以处理重叠数组,而
strcpy()
不能保证正确执行此操作。 但是,此代码假设要插入的字符串不与原始字符串重叠:

void strinsert (char *str, size_t pos, const char *insertstr) 
{
    char *where =str+pos; 
    memcpy(where+strlen(insertstr), where, strlen(where)+1);
    memcpy(where, insertstr, strlen(insertstr));
}  

使用示例:

char mystring[100]; 
strcpy (mystring, "abcdef");
strinsert (mystring, 3, "123"); 
printf ("Altered string: %s\n", mystring); 

然而,这是一个不安全的版本,因为必须在其他地方执行是否有足够空间的检查,并且不幸的是,缓冲区溢出很常见。

案例 2:相同但安全的版本

以下代码不使用

strnlen_s()
memcpy_s()
,它们会另外检查具有 NULL 指针或零长度的边界情况,因为这些函数在许多实现中不可用。 但这已经可以防止常见的缓冲区大小问题:

int strinsert_s (char *str, size_t pos, size_t strsz, 
                       const char *insertstr, size_t inssz) 
{
    char *where =str+pos; 
    size_t wheresz = strsz-pos;       // maximum size at insert point 
    size_t insertlen = strnlen(insertstr,inssz);
    if (pos>=strsz || pos>=strlen(str) ) // if insert pos invalid 
        return EOVERFLOW; 
    size_t wl = strnlen(where,wheresz); 
    if (wl<wheresz) // if null terminated take the trailing '\0' 
       wl++;
    if (wheresz<=insertlen || wheresz-insertlen<=wl) // if  insert string too large
        return EOVERFLOW;    
    memcpy (where+insertlen, where, wl);
    memcpy (where, insertstr, insertlen);
    return 0;  
}  

使用示例:

char mystring[100]; 
strcpy (mystring, "abcdef");
errno_t err = strinsert_s (mystring, 3, sizeof(mystring), "123",4); 
if (err) 
    printf ("Error %d\n", err); 
else printf ("Altered string: %s\n", mystring); 

防止缓冲区溢出的示例:

char mystring[9]; // the trailing '\0' will go out of buffer - nasty! 
strcpy (mystring, "abcdef");
int err = strinsert_s (mystring, 3, sizeof(mystring), "123",4); 
if (err) 
    printf ("Error %d\n", err); 
else printf ("Altered string: %s\n", mystring); 

-1
投票
char *strInsert(char *str1, const char *str2, int pos) {
    size_t l1 = strlen(str1);
    size_t l2 = strlen(str2);

    if (pos <  0) pos = 0;
    if (pos > l1) pos = l1;

    char *p  = str1 + pos;
    memmove(p + l2, p, l1 - pos);
    memcpy (p, str2,  l2);
    return str1;
}
© www.soinside.com 2019 - 2024. All rights reserved.