Я попытался реализовать strinsert и вставил его ниже.Он компилируется и тесты проходят с VS2010.
Функция получает указатель на целевой буфер, размер целевого буфера, строку для вставки и местоположение для вставки строки.Функция возвращает -1 в случае ошибки, в противном случае она возвращает размер буфера назначения.Если целевой буфер слишком мал, чтобы вместить вставленную строку, он изменяет размер буфера с помощью realloc и возвращает новый размер буфера.
Я использовал memmove вместо strncpy, так как я считаю, что strncpy не определен, когда источник и пункт назначения перекрываются,Это может быть возможно, если вставленная строка меньше объема перемещаемой памяти.
#include "stdafx.h"
#include <string.h>
#include <stdlib.h>
#include <malloc.h>
#include <assert.h>
int strinsert(char **dest, size_t destsize, char *ins, size_t location)
{
size_t origsize = 0;
size_t resize = 0;
size_t inssize = 0;
if (!dest || !ins)
return -1; // invalid parameter
if (strlen(ins) == 0)
return -1; // invalid parameter
origsize = strlen(*dest);
inssize = strlen(ins);
resize = strlen(*dest) + inssize + 1; // 1 for the null terminator
if (location > origsize)
return -1; // invalid location, out of original string
// resize string to accommodate inserted string if necessary
if (destsize < resize)
*dest = (char*)realloc(*dest, resize);
// move string to make room for insertion
memmove(&(*dest)[location+inssize], &(*dest)[location], origsize - location);
(*dest)[origsize + inssize] = '\0'; // null terminate string
// insert string
memcpy(&(*dest)[location], ins, inssize);
return max(destsize, resize); // return buffer size
}
void check(int retVal)
{
if (retVal < 0)
{
assert(!"error code returned!\n");
exit(1);
}
}
#define STARTSTRING "Hello world!"
int _tmain(int argc, _TCHAR* argv[])
{
// initialize str
int bufsize = strlen(STARTSTRING) + 1 + 10; // added 1 for null terminator and 10 to test resize on demand
int prevbufsize = 0;
char *str = (char*)malloc(bufsize);
strncpy_s(str, bufsize, STARTSTRING, strlen(STARTSTRING));
printf("str = %s\n", str);
// test inserting in the middle
prevbufsize = bufsize;
bufsize = strinsert(&str, bufsize, "awesome ", 6);
assert(bufsize == prevbufsize); // this should not resize the buffer as it has room for 10 more bytes
check(bufsize);
printf("str = %s\n", str);
// test inserting at front
prevbufsize = bufsize;
bufsize = strinsert(&str, bufsize, "John says ", 0);
assert(bufsize > prevbufsize);
check(bufsize);
printf("str = %s\n", str);
// test inserting char in the middle
prevbufsize = bufsize;
bufsize = strinsert(&str, bufsize, "\"", 10);
assert(bufsize > prevbufsize);
check(bufsize);
printf("str = %s\n", str);
// test inserting char at end
prevbufsize = bufsize;
bufsize = strinsert(&str, bufsize, "\"", strlen(str));
assert(bufsize > prevbufsize);
check(bufsize);
printf("str = %s\n", str);
free(str);
return 0;
}
Вот вывод:
str = Hello world!
str = Hello awesome world!
str = John says Hello awesome world!
str = John says "Hello awesome world!
str = John says "Hello awesome world!"