Remove specified number of characters from a string From an exercise in Kochan's Programming in C, following a chapter on C's null-terminated strings:


  Write a function called removeString to remove a specified number of
  characters from a character string. The function should take three
  arguments: the source string, the starting index number in the source
  string, and the number of characters to remove. So, if the character
  array text contains the string "the wrong son", the call
  
  removeString (text, 4, 6);
  
  has the effect of removing the characters “wrong “ (the
  word “wrong” plus the space that follows) from the array text. The
  resulting string inside text is then "the son".


I found the exercise interesting to implement. I know I could have used strlen to get the length of the string, but I like the idea of handling everything in a single pass (I imagine strlen has to traverse the characters looking for a null-byte).

Any comments/criticisms are welcome. Here's my solution:

void removeString (char text[], int index, int rm_length)
{
    int i;

    for ( i = 0; i &lt; index; ++i )
        if ( text[i] == '\0' )
            return;

    for ( ; i &lt; index + rm_length; ++i )
        if ( text[i] == '\0' ) {
            text[index] = '\0';
            return;
        }

    do {
        text[i - rm_length] = text[i];
    } while ( text[i++] != '\0' );
}


And a test drive

int main (void)
{
    char string1[] = "the wrong son";
    char string2[] = "the wrong son";
    char string3[] = "the wrong son";

    printf ("string1: %s\n", string1);
    printf ("string2: %s\n", string2);
    printf ("string3: %s\n\n", string3);

    printf ("removeString (string1, 13, 6)\n");
    removeString (string1, 13, 6);
    printf ("string1: %s\n\n", string1);

    printf ("removeString (string2, 11, 6)\n");
    removeString (string2, 11, 6);
    printf ("string2: %s\n\n", string2);

    printf ("removeString (string3, 4, 6)\n");
    removeString (string3, 4, 6);
    printf ("string3: %s\n\n", string3);

    return 0;
}


Output:

string1: the wrong son
string2: the wrong son
string3: the wrong son

removeString (string1, 13, 6)
string1: the wrong son

removeString (string2, 11, 6)
string2: the wrong s

removeString (string3, 4, 6)
string3: the son
One quick stylistic comment.

Braces

for ( ; i &lt; index + rm_length; ++i )
    if ( text[i] == '\0' ) {
        text[index] = '\0';
        return;
    }


Constructs like this are begging to have a subtle hidden bug in them. Always use braces if you have more than a single statement inside a for/if statement.

for (; i &lt; index + rm_length; ++i) {
    if ( text[i] == '\0' ) {
        text[index] = '\0';
        return;
    }
}