0

I wrote the following program to add a '*' character after every vowel in a C string

#include <iostream>
#include <string.h>
using namespace std;

int main()
{
char s[99];
cin.get(s, 99);

char aux[99];

for (int i = 0; i < strlen(s); i++)
    if(strchr("aeiou", s[i])){
        strcpy(aux, s + i);
        strcpy(s + i + 1, aux);

        s[i+1] = '*';
    }

cout << s;
return 0;
}

So if I enter the word brain it will output bra*i*n and it works perfectly fine. However if I get rid of that 'aux' string and instead of doing strcpy(aux, s + i); strcpy(s + i + 1, aux); I just do strcpy(s + i + 1, s + i); my program stops working. (Infinite looping, doesn't return 0). Why is that?

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312
Lastrevio2
  • 51
  • 6
  • Think about it. `strcpy(s + i + 1, s + i);` is copying the string while it is changing the part it hasn't copied yet – lurker Oct 19 '19 at 12:11
  • you cannot use `strcpy(dst, src)` (or `memcpy(dst, src, len)`) when `dst` and `src` point somewhere inside the same object. – pmg Oct 19 '19 at 12:16
  • `` and `cin.get` are C++ features, but you tagged this question with C. – Eric Postpischil Oct 19 '19 at 12:16
  • @astrevio2 In general case there can be not enough space in the source string to accommodate all inserted characters '*' after vowels. So in general your program has undefined behavior. you need to allocate the auxiliary array dynamically. – Vlad from Moscow Oct 19 '19 at 12:35
  • @pmg @lurker @user3121023 If that is true then why does it always work to delete character at index i in a string by using `strcpy(s + i, s + i + 1);` yet when I reverse `s+i+1` with `s+i` it suddenly breaks down? – Lastrevio2 Oct 19 '19 at 12:44
  • This code is violating a constraint of `strcpy`, since the source and destination overlap. Since this is C++, a `std::string` should be used instead of C style character arrays. – Eljay Oct 19 '19 at 12:51
  • @Lastrevio2: it's UB. If it *"works"* now it's because you're out of luck. Surely it will stop *"working"* when the compiler is upgraded, when you switch computers, when you change something (apparently) unrelated in the code, ... – pmg Oct 19 '19 at 13:15
  • @Lastrevio2 You need to understand how `strcpy()` is (usually) implemented. It takes the source byte, and checks if it's `NUL`. If not, it copies it to the destination byte, increments `source` and `dest`, then loops back for more. When that copies **backwards**, it works: `source` overwrites characters *behind* where it's already been. When that copies **forwards**, `source` overwrites `dest` *before* it reads it - you've just clobbered the `NUL`. – John Burger Oct 19 '19 at 15:48

0 Answers0