Here's some working code, which gives me the output:
String: <<20120910T090000>>
String: <<2012-0910T090000>>
String: <<2012-09-10T090000>>
String: <<2012-09-10-T090000>>
String: <<2012-09-10-T-090000>>
String: <<2012-09-10-T-0900-00>>
It uses memmove()
because it is guaranteed that the strings being copied around overlap.
#include <assert.h>
#include <string.h>
#include <stdio.h>
static void insert(char *str, size_t len, char c, size_t pos)
{
memmove(&str[pos+1], &str[pos], len - pos + 1);
str[pos] = c;
}
int main(void)
{
char string[25] = "20120910T090000";
// I want to make it something like "2012-09-10-T-0900-00"
char inschr[] = "-----";
int inspos[] = { 4, 7, 10, 12, 17 };
enum { NUMCHR = sizeof(inschr) / sizeof(inschr[0]) };
enum { NUMPOS = sizeof(inspos) / sizeof(inspos[0]) };
assert(NUMCHR == NUMPOS + 1);
size_t length = strlen(string);
printf("String: <<%s>>\n", string);
for (int i = 0; i < NUMPOS; i++)
{
insert(string, length, inschr[i], inspos[i]);
length++;
printf("String: <<%s>>\n", string);
}
return(0);
}
Of course, I'm assuming C99 support with the for
loop notation. Note, too, that in classic C style, the code does not take the size of the target string, so it does not ensure that there is no buffer overflow. It wouldn't be all that hard to add the parameter and do the check; the problem area is how to indicate that the function failed. You could use a different interface to the function, taking arbitrary length strings to be inserted at arbitrary positions; it isn't significantly harder...
String: <<20120910T090000>>
String: <<2012-0910T090000>>
String: <<2012-09-10T090000>>
String: <<2012-09-10-T090000>>
String: <<2012-09-10-T-090000>>
String: <<2012-09-10-T-0900-00>>
#include <assert.h>
#include <string.h>
#include <stdio.h>
static int insert(char *str, size_t max, size_t len, char *ins, size_t pos)
{
assert(str[len] == '\0');
assert(len < max);
size_t inslen = strlen(ins);
if (len + inslen + 1 >= max)
return -1;
memmove(&str[pos+inslen], &str[pos], len - pos + inslen);
memmove(&str[pos], ins, inslen);
return len + inslen;
}
int main(void)
{
char string[25] = "20120910T090000";
// I want to make it something like "2012-09-10-T-0900-00"
char *insstr[] = { "-", "-", "-", "-", "-" };
int inspos[] = { 4, 7, 10, 12, 17 };
enum { NUMSTR = sizeof(insstr) / sizeof(insstr[0]) };
enum { NUMPOS = sizeof(inspos) / sizeof(inspos[0]) };
size_t length = strlen(string);
assert(NUMSTR == NUMPOS);
printf("String: <<%s>>\n", string);
for (int i = 0; i < NUMPOS; i++)
{
int newlen = insert(string, sizeof(string), length, insstr[i], inspos[i]);
if (newlen < 0)
{
printf("Oops! failed to insert [%s] into [%s]\n", insstr[i], string);
break;
}
length = newlen;
printf("String: <<%s>>\n", string);
}
return(0);
}