#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?
CodePudding user response:
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)
- ... 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
CodePudding user response:
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);