5

So, I have seen this strcpy implementation in C:

void strcpy1(char dest[], const char source[])
{
    int i = 0;
    while (1)
    {
        dest[i] = source[i];

        if (dest[i] == '\0')
        {
            break;
        }

        i++;
    } 
}

Which to me, it even copies the \0 from source to destination.

And I have also seen this version:

// Move the assignment into the test
void strcpy2(char dest[], const char source[]) 
{
    int i = 0;
    while ((dest[i] = source[i]) != '\0')
    {
        i++;
    } 
}

Which to me, it will break when trying to assign \0 from source to dest.

What would be the correct option, copying \0 or not?

Ziezi
  • 6,375
  • 3
  • 39
  • 49
Hommer Smith
  • 26,772
  • 56
  • 167
  • 296

10 Answers10

8

The code should look like as follows:

char * strcpy(char *strDest, const char *strSrc)
{
    assert(strDest!=NULL && strSrc!=NULL);
    char *temp = strDest;
    while(*strDest++ = *strSrc++); // or while((*strDest++=*strSrc++) != '\0');
    return temp;
}

You can NOT delete the second line char *temp = strDest; and directly return strDest. This will cause error for the returned content. For example, it will not return correct value (should be 22) will checking the length of returned char *.

char src_str[] = "C programming language";
char dst_str[100];
printf("dst_str: %d\n", strlen(strcpy(dst_str, src_str)));
herohuyongtao
  • 49,413
  • 29
  • 133
  • 174
  • Is there any best way than the above? – anil kumar Oct 18 '15 at 07:45
  • Just a note: In your example, you store the beginning of the `dest` string to avoid returning its end after the copy is complete, which is right, but his functions (have return type `void` and) pass the parameters by value, thus the (local) pointer arithmetic does not influence the pointer outside, so `temp` (i.e. start address) is not mandatory, no? – Ziezi Jun 09 '17 at 09:31
4

Both copy the terminator, thus both are correct.

Note that strcpy2() does the assignment (the copying) first, then the comparison. So it will copy the terminator before realizing it did, and stopping.

Also, note that functions whose names start with str are reserved, so neither of these are actually valid as "user-level" code.

unwind
  • 391,730
  • 64
  • 469
  • 606
  • So the last assignment of (dest[i] = source[i]) returns '\0'? I thought that assignments returned always "1" or true, if they were correct assigned. – Hommer Smith Jan 23 '13 at 10:00
  • 1
    @Assignments evaluate to the value assigned. I'm not at all sure what you mean by "correct assigned". What would an example of an "incorrect assignment" be? I don't think that concept exists, in C. – unwind Jan 23 '13 at 10:07
  • 1
    Only names beginning with “str” **and** a lowercase letter are reserved, per C 2011 7.31.12 and .13. – Eric Postpischil Jan 23 '13 at 11:33
  • What if the size of dest is unknown in the function strcpy? How to do safe copy? – Dr. Essen Mar 21 '18 at 15:52
2

You're wrong. Both copy the \0 (NUL terminator) character. You have to copy the NUL terminator character always or your string will be broken: you'll never know when/where it ends.

m0skit0
  • 25,268
  • 11
  • 79
  • 127
1

Both copy the terminator, thus both are correct.

strcpy2() does the copying first, then the compares. Thus it will copy the terminator and stops.

The functions whose names start with str are reserved, so use any other variables or naming types

HariRHK
  • 11
  • 5
1

It is recommended not to advance the input pointers to the source and destination memory spaces, since the pointers will be used in main right away.

I've mentioned alternate methodical syntax, where in case someone might wonder the code output.

void strcpy1(char * s, char * p)
{
    char * temp1 = s;
    char * temp2 = p;
    while(*temp1 != '\0')
    {
        *temp2 = *temp1;
        temp1++;
        temp2++;
    }
    *temp2 = '\0';
}

void main()
{
    char * a = "Hello";
    char b[10];

    strcpy1(a,b);
    printf("%s", b);
    
    return 0;
}
AS_eem
  • 11
  • 1
0

Both strcpy1() and strcpy2() does the same. Both copy the NUL character to the end of the destination array.

sr01853
  • 6,043
  • 1
  • 19
  • 39
0
char * strcpy(char *strDest, const char *strSrc)
{
    assert(strDest!=NULL && strSrc!=NULL);
    assert(strSrc + strlen(strSrc) < d || strSrc > strDest);  // see note

    char *temp = strDest;
    while(*strDest++ = *strSrc++)
        ;
    return temp;
}

// without the check on line 4, the new string overwrites the old including the null deliminator, causing the copy unable to stop.

sbi
  • 219,715
  • 46
  • 258
  • 445
0

Here is full implementation. You do not have to consider the \0 at the end in the first string, it will be copied automatically from the second string as per logic

//str copy function self made
char *strcpynew(char *d, char *s){
   char *saved = d;
   while ((*d++ = *s++) != '\0');

   return saved; //returning starting address of s1
}

//default function that is run by C everytime
int main(){

    //FOR STRCPY 
    char s1[] = "rahul"; //initializing strings
    char s2[] = "arora"; //initializing strings
    strcpynew(s1, s2);
    printf("strcpy: %s\n", s1); //updated string after strcpy
}
Rahul Arora
  • 4,503
  • 1
  • 16
  • 24
0

You can use this code, the simpler the better ! Inside while() we copy char by char and moving pointer to the next. When the last char \0 will pass and copy while receive 0 and stop.

    void StrCopy( char* _dst, const char* _src )
    {
       while((*_dst++ = *_src++));
    }
  • While this code snippet may be the solution, [including an explanation](//meta.stackexchange.com/questions/114762/explaining-entirely-‌​code-based-answers) really helps to improve the quality of your post. Remember that you are answering the question for readers in the future, and those people might not know the reasons for your code suggestion. – peacetype Feb 24 '18 at 21:29
-3

Both copy the '\0'. That's what you have to do if you want to fully emulate the original strcpy

Davide Berra
  • 6,387
  • 2
  • 29
  • 50