2

I'm learning string functions in C and I can't seem to get my teacher's demo using strcpy() to remove white spaces to work on my machine while it works perfectly fine for him. Here's the source code:

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

int main()
{
    char s[20]="abc   def   ghi";
    char *ptr = strstr(s, "  ");
    while(ptr!=NULL)
    {
        printf("Before trim: %s\n", s);
        strcpy(ptr, ptr+1);
        printf("After trim : %s\n", s);
        printf("\n");
        ptr = strstr(s, "  ");
    }
    return 0;
}

Expected result:

Before trim: abc   def   ghi
After trim : abc  def   ghi

Before trim: abc  def   ghi
After trim : abc def   ghi

Before trim: abc def   ghi
After trim : abc def  ghi

Before trim: abc def  ghi
After trim : abc def ghi

Actual result:

Before trim: abc   def   ghi
After trim : abc  def   ghi

Before trim: abc  def   ghi
After trim : abc def   ghi

Before trim: abc def   ghi
After trim : abc def  hhi

Before trim: abc def  hhi
After trim : abc def hii

I've searched for this error and learned that strcpy() is unsafe because it may cause overflow or undefined behavior. Most of the search I've read is about the destination buffer is not large enough. I don't know the keyword of this strange behavior. Can someone please explain to me what am I doing wrong? Thank you in advance!

anastaciu
  • 23,467
  • 7
  • 28
  • 53
Tai Nguyen
  • 31
  • 1
  • 6
  • 7
    Welcome to SO. According to the manual, source and destination buffer are not allowed to overlap. You violate this rule – Gerhardh Mar 23 '20 at 14:23
  • 2
    Use a temporary buffer to perform the copy such as `s1[20]`. – Roberto Caboni Mar 23 '20 at 14:24
  • 1
    You can use `memmove` if source and destination overlap, but you have to compute the length and pass that too. Note that `strcpy` is not guaranteed to fail: it is not guaranteed to succeed, which isn't the same thing. – Weather Vane Mar 23 '20 at 14:31
  • 3
    I think you should ask your teacher to explain why their code does not work ;) – Weather Vane Mar 23 '20 at 15:36

1 Answers1

1
char *strcpy( char *restrict dest, const char *restrict src ); //(since C99)

Copies the null-terminated byte string pointed to by src, including the null terminator, to the character array whose first element is pointed to by dest.

The behavior is undefined if the dest array is not large enough. The behavior is undefined if the strings overlap. The behavior is undefined if either dest is not a pointer to a character array or src is not a pointer to a null-terminated byte string.

https://devdocs.io/c/string/byte/strcpy

This is the kind of thing a teacher should be careful with, though I must say that compiling the code with several versions of MSVC, clang and gcc I was never able to reproduce the described actual result.

Community
  • 1
  • 1
anastaciu
  • 23,467
  • 7
  • 28
  • 53