好的,所以我有一个 char stringA 和 char stringB,我希望能够将 stringB 插入到 stringA 的 x 点。
char *stringA = "abcdef";
char *stringB = "123";
产品为
"ab123cdef"
有人知道该怎么做吗?预先感谢
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);
说明:
希望有帮助。
备注:记住让 strC 足够长以包含 strA 和 strC,否则会产生分段错误。您可以通过将字符串声明为数组来完成此操作,就像我的示例中一样。
stringA 和 stringB 都是指针 - 它们包含内存块的起始地址。 它们指向的内存分别包含连续的字符串:“abcdef”和“123”。 由于字符串是连续的块内存(意味着给定字符的内存位置是前一个字符之后的一个字节),因此如果不先移动一些字符,则无法将更多字符插入到字符串中间。 在你的情况下,你甚至不能真正做到这一点,因为为每个字符串分配的内存量足够大,足以容纳该字符串(忽略填充)。
您要做的是将字符串复制到您为此目的分配的另一个内存块,然后复制它们,以便第二个字符串在第一个字符串中以 x 个字符开头。
其他几个 SO 用户已经发布了代码解决方案,但我认为您应该尝试自己找到确切的解决方案(希望我对正在发生的事情的高级解释会有所帮助)。
这里有一个更通用的解决方案。
注意,
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);
}
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);
这里有很多答案。 然而,大多数确实依赖于
strcat()
,而不是使用高效为分配计算的长度,没有一个是安全,也没有一个提供就地插入的解决方案。
只需将不同的字符串组件复制到其目标地址,避免使用
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); 免费;
我将把这个版本强化为安全版本作为练习。
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);
然而,这是一个不安全的版本,因为必须在其他地方执行是否有足够空间的检查,并且不幸的是,缓冲区溢出很常见。
以下代码不使用
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);
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;
}