What's the difference between strcpy and stpcpy?

后端 未结 6 940
不知归路
不知归路 2021-01-01 12:57

While reading the man page for strcpy, I discovered the function stpcpy also exists. However, the only difference I could notice in the man page is

相关标签:
6条回答
  • 2021-01-01 13:31

    The question you are asking in the title and the question about restrict are actually two different totally unrelated questions. The other answers have already provided you with some good links that will help you to learn more about restrict.

    However, the main difference between these two functons in not really the restrict specifier. In fact, in C99 version of C language specification, strcpy also has restrict qualification on its parameters. What you see on your man page for strcpy is simply not updated to conform to C99.

    The main difference (which you seem to have missed) is the return value of stpcpy. stpcpy returns the pointer to the terminating \0 character of the target string. This immediately makes clear the purpose of stpcpy and the rationale behind its existence: this function is intended to be used as an intelligent replacement to strcat function in situations when you need to concatenate multiple sub-strings into one string. You see, strcat works pretty poorly in such application (I'd even say that strcat has no meaningful uses in real code). The problem with strcat is that it rescans the destination string every time you add something to it, thus doing lots of unnecessary work and basically generating more heat than light. For example, the following code suffers from that problem

    const char *part1, *part2, *part3, *part4;
    ...
    char buffer[size]; /* assume that `size` is calculated properly */
    
    strcpy(buffer, part1);
    strcat(buffer, part2);
    strcat(buffer, part3);
    strcat(buffer, part4);
    

    This code can be reimplemented in a much more reasonable way by using stpcpy

    stpcpy(stpcpy(stpcpy(stpcpy(buffer, part1), part2), part3), part4);
    

    And if you don't like chained calls, you can use an intermediate pointer to store the return value of intermediate stpcpy calls

    char *end = buffer;
    
    end = stpcpy(end, part1);
    end = stpcpy(end, part2);
    end = stpcpy(end, part3);
    end = stpcpy(end, part4);
    

    Of course it is worth mentioning that strcpy and strcat are standard functions, while stpcpy is not.

    0 讨论(0)
  • 2021-01-01 13:32

    The other difference is the return value. From the man page: "The strcpy() and strncpy() functions return s1. The stpcpy() function returns a pointer to the terminating `\0' character of s1."

    0 讨论(0)
  • 2021-01-01 13:41

    strcpy returns s1 but stpcpy returns s1+strlen(s2).

    0 讨论(0)
  • 2021-01-01 13:46

    The restrict tells the compiler that s1 and s2 point to different arrays and that there is no overlap in the pointed-to arrays. In some cases this may allow the compiler to perform extra optimizations (i.e., it could possibly copy blocks of multiple characters without having to check for overlap).

    Note also that the return value is different: stpcpy returns a pointer to the \0 that was copied into the destination buffer while strcpy returns a pointer to the beginning of the string (effectively it does a return s1;).

    0 讨论(0)
  • 2021-01-01 13:47

    The stpcpy() function copies the string pointed to by src (including the terminating '\0' character) to the array pointed to by dest. The strings may not overlap, and the destination string dest must be large enough to receive the copy.

    This satisfies the requirements for restrict, even if it's not in the function signature. If C99 is present, it could be added.

    stpcpy() returns a pointer to the end of the string dest (that is, the address of the terminating null byte) rather than the beginning.

    This enables you to concatenate many strings more easily, and more efficiently, as src can be "tacked" onto the pointer returned from the last stpcpy(). The naive implementation of the alternative, strcat has to locate the end of the dest string before it can commence copying.

    Note the following:

    This function is not part of the C or POSIX.1 standards, and is not customary on Unix systems, but is not a GNU invention either. Perhaps it comes from MS-DOS. Nowadays, it is also present on the BSDs.

    0 讨论(0)
  • 2021-01-01 13:53

    Wikipedia entry for restrict

    In short, restrict tells the compiler that the segments of memory pointed to by s1 and s2 do not overlap; this allows the code to perform less error checking.

    0 讨论(0)
提交回复
热议问题