C program to delete n Characters from a given position in a given string.

Deleting n characters from a given position in a string is a common string manipulation task used in text editors, parsers, and data cleaning. The approach: shift all characters after the deleted region one step to the left, overwriting the deleted characters, then terminate the string with a null byte.

The original post used gets() (removed in C11, unsafe buffer overflow) and a strcpy()-based approach. This rewrite uses a manual shift loop — no library functions beyond strlen() — and supports 1-based position input.

Algorithm

  1. Convert the 1-based pos to a 0-based index: start = pos - 1.
  2. Clamp n if deleting past the end: n = min(n, len - start).
  3. Shift all characters at index start+n and beyond one position to the left.
  4. Add a null terminator at the new end.

C Program to Delete n Characters from a String

/* Delete n characters from a given position in a string
 * position is 1-based (position 1 = first character)
 * Compile: gcc -ansi -Wall -Wextra delchars.c -o delchars */
#include <stdio.h>
#include <string.h>

void delete_chars(char *str, int pos, int n)
{
    int len = (int)strlen(str);
    int start, i;

    if (pos < 1 || pos > len || n < 1) return;  /* nothing to delete */

    start = pos - 1;  /* convert 1-based pos to 0-based index */

    if (start + n > len)
        n = len - start;  /* clamp: don't delete past end of string */

    /* shift characters left: overwrite the deleted region */
    for (i = start; str[i + n] != '\0'; i++)
        str[i] = str[i + n];
    str[i] = '\0';  /* terminate */
}

int main(void)
{
    char s1[100] = "Hello, World!";
    char s2[100] = "abcdefghij";
    char s3[100] = "Programming";

    printf("Original: \"%s\"\n", s1);
    delete_chars(s1, 8, 5);  /* delete "World" (pos 8, 5 chars) */
    printf("After delete_chars(s, 8, 5): \"%s\"\n\n", s1);

    printf("Original: \"%s\"\n", s2);
    delete_chars(s2, 3, 4);  /* delete "cdef" (pos 3, 4 chars) */
    printf("After delete_chars(s, 3, 4): \"%s\"\n\n", s2);

    printf("Original: \"%s\"\n", s3);
    delete_chars(s3, 1, 3);  /* delete "Pro" (pos 1, 3 chars) */
    printf("After delete_chars(s, 1, 3): \"%s\"\n", s3);

    return 0;
}

How to Compile and Run

gcc -ansi -Wall -Wextra delchars.c -o delchars
./delchars

Sample Output

Original: "Hello, World!"
After delete_chars(s, 8, 5): "Hello, !"

Original: "abcdefghij"
After delete_chars(s, 3, 4): "abghij"

Original: "Programming"
After delete_chars(s, 1, 3): "gramming"

Step-by-Step Trace: “Hello, World!”, delete 5 at pos 8

Index:   0  1  2  3  4  5  6  7  8  9  10 11 12 '\0'
Char:    H  e  l  l  o  ,     !  W  o  r  l  d   !   [before: indices shifted]

Wait — let me verify:
"Hello, World!"
 H=0 e=1 l=2 l=3 o=4 ,=5  =6 W=7 o=8 r=9 l=10 d=11 !=12

pos=8 → start = 7 (0-based) → char at index 7 is 'W'
Delete 5 from index 7: W=7, o=8, r=9, l=10, d=11
Shift index 12 ('!') → index 7, then '\0' → index 8
Step String state What happened
Before “Hello, World!” len=13, start=7, n=5
Shift ‘!’ “Hello, !orld!” str[7]=’!’ (was str[12])
Terminate “Hello, !” str[8]=’\0′

Code Explanation

  • 1-based position — text editors and most human descriptions count characters starting from 1. The function converts to 0-based index internally: start = pos - 1. If the user says “position 8”, we delete from array index 7.
  • Clamping n — if pos=9 and n=10 in a 13-character string, we can only delete 4 characters (not 10). The clamp prevents the shift loop from reading uninitialized memory: n = len - start limits n to the remaining characters.
  • The shift loop: str[i] = str[i + n] — each iteration moves a character n positions to the left, overwriting the deleted region. The loop runs while str[i+n] != '\0', which copies the null terminator exactly once at the end via the str[i] = '\0' after the loop.
  • No memmove needed — since we are always moving data to lower indices (left shift), a simple left-to-right copy loop is safe. memmove() would be needed if the source and destination regions could overlap in either direction. Here they do overlap (the destination starts inside the source range), but left-to-right iteration handles it correctly.
  • Modify in-place — the function takes char *str (a pointer to a modifiable buffer), not const char *. Passing a string literal like delete_chars("hello", 1, 2) would invoke undefined behavior — string literals are read-only.

What This Program Teaches

  • In-place string modification — shifting characters left is the fundamental technique behind text deletion in any language. The same shift pattern appears in array deletion, circular buffer management, and parser token consumption.
  • Null terminator management — after the shift, the string must be manually terminated with '\0'. Missing the terminator is a classic C string bug: subsequent operations would read garbage data past the intended end.
  • Input validation before array access — checking pos < 1 || pos > len before computing start prevents out-of-bounds reads. The clamp n = len - start prevents out-of-bounds shifts. Together they make the function safe for any integer inputs.
  • Why not strcpy herestrcpy(str + start, str + start + n) would also work but relies on undefined behavior when source and destination overlap (which they do here — same buffer, overlapping regions). memmove() is the safe library call for overlapping copies; the manual loop is also correct for left shifts.

Related Programs

Recommended book:
The C Programming Language — Kernighan & Ritchie (India) |
(US)
 | 
C Programming: A Modern Approach — K.N. King (India) |
(US)

Practice what you learned: C Aptitude Questions — or try our C Programming Quiz App on Android.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>