John Li
John Li

Reputation: 33

how to insert multiple characters in a string in C

I wish to insert some characters into a string in C:

Example: char string[100] = "20120910T090000";

I want to make it something like "2012-09-10-T-0900-00"

My code so far:

void append(char subject[],char insert[], int pos) {
    char buf[100]; 

    strncpy(buf, subject, pos); 

    int len = strlen(buf);

    strcpy(buf+len, insert); 

    len += strlen(insert);  

    strcpy(buf+len, subject+pos); 
    strcpy(subject, buf);   
}

When I call this the first time I get: 2012-0910T090000

However when I call it a second time I get: 2012-0910T090000-10T090000

Any help is appreciated

Upvotes: 3

Views: 3871

Answers (2)

AndersK
AndersK

Reputation: 36092

You could do something like this:

  char src[100] = "20120910T090000";
  char mask[] = "NNNN-NN-NN-C-NN-NN-NN";
  char dest[100] = {0};

  for (size_t s = 0,m = 0, d = 0; s < strlen(src) && m < strlen(mask); ++m)
  {
    switch (mask[m])
    {
    case 'N':
      assert(isdigit(src[s]));
      dest[d++] = src[s++];
      break;
    case 'C':
      assert(isalpha(src[s]));
      dest[d++] = src[s++];
      break;
    default:
      dest[d++] = mask[m];
      break;
    }
  }

Upvotes: 1

Jonathan Leffler
Jonathan Leffler

Reputation: 755044

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);
}

Upvotes: 2

Related Questions