1
#include <stdio.h>
#include <string.h>

int main() {
    char buffer[200] = "This is a string";
    char buffer1[200];
    strcpy(buffer1, buffer);
    char vowels[] = "aeiouAEIOU";
    int i;

    for (i = 0; i < strlen(buffer); i++) {
        if (strchr(vowels, buffer[i]) != NULL) {
            char tmp[1000];
            strcpy(tmp, buffer + i + 1);
            strcpy(buffer + i, tmp);
            
            strcpy(buffer1 + i, buffer1 + i + 1);
            break;
        }
    }

    printf("buffer=%s\n", buffer); // prints "Ths is a string", which is OK
    printf("buffer1=%s\n", buffer1); // prints "Ths is asstring", which is not OK.
    return 0;
}

I'm trying to remove a character from a string.
In the code below I used to 2 ways to achieve this, with the variables buffer and buffer1. But, one of them, buffer1, prints a weird result.

What makes buffer and buffer1 contain different values?

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
sandrino
  • 65
  • 1
  • 7

2 Answers2

2

Do not overlap

char *strcpy(char * restrict s1, const char * restrict s2); has restrict which informs the caller to not provide pointers to overlapping data.

OP's code used overlapping data and so has undefined behavior (UB).
Don't do that.


Could use memmove() which handles overlapping data.

size_t sz = strlen(buffer1 + i + 1) + 1;
memmove(buffer1 + i, buffer1 + i + 1, sz);
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
2

Using strcpy for overlapping arrays invokes undefined behavior. In such a case you should use memmove.

From the C Standard (7.23.2.3 The strcpy function)

  1. ... If copying takes place between objects that overlap, the behavior is undefined.

Here is a demonstration program

#include <stdio.h>
#include <string.h>

int main( void )
{
    char buffer[200] = "This is a string";
    char vowels[] = "aeiouAEIOU";

    size_t n = strlen( buffer );

    size_t pos = strcspn( buffer, vowels );

    memmove( buffer + pos, buffer + pos + 1, n - pos );

    puts( buffer );
}

The program output is

Ths is a string
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335