C like Cpp code to do strncpy and copy a string to a buffer which is not long enough The code works, but I guess it could be much better.

/*
DESCRIPTION
The strncpy() function is similar, except that at most n bytes of src
are copied. Warning: If there is no null byte among the first n bytes
of src, the string placed in dest will not be null-terminated.
NOTE
If the length of src is less than n, strncpy() pads the remainder of
dest with null bytes.
*/

char *strncpy(char *dest, const char *src, size_t n)
{
    size_t i = 0;
    char *d = dest;
    while ((i++ &lt; n) &amp;&amp; (*d++ = *src++));
    while (i++ &lt; n)
    {
        *d++ = 0;
    }
    return dest;
}


/*
DESCRIPTION
The stlcpy() function copies the string pointed to by src.
to the buffer pointed to by dest.
The strings may not overlap.
NOTE
The destination string dest may *NOT* be
large enough to receive the copy, then the truncation happpens.
size_d is the size of destination buffer.
*/

char *strlcpy(char *dest, const char *src, size_t size_d)
{
    size_t i = 0;
    char * d = dest;
    while ((i &lt; size_d) &amp;&amp; (*d++ = *src++)) i++;
    if (i &lt; size_d)//everything copied.
    {
        if (i &lt; size_d -1)
        {
            *d = 0;
        }
        else
        {
            //truncating the last char.
            dest[i-1] = 0;
        }
    }
    else if (i == size_d)
    {
        //truncating the src, size_d - 1 bytes copied.
        dest[i-1] = 0;
    }
    else
    {
        //i &gt; size_d, impossible.
    }
    return dest;
}
Since you have written it for practice (as indicated in your comment), and strncpy has been implemented in various platforms in rather similar manner, I assume that you want comment on the function behavior itself and not specifically whether it conforms to the strncpy POSIX function.

I am aware that the second function strlcpy handles many of the criticisms below, but there is no indication in your question that you have considered these.

My first problem with the strncpy is that it allows no indication of failure or indication of any behavior even though there is a possibility of a few different behaviors that the user may be interested in.


The first n characters may not contain a \0
Did we truncate at n? or was the src small enough?
How many characters were copied?


We are using the return value by returning the dest even though this information is no different from the parameter that was passed in.

Secondly, if the buffer was small enough, the function is zeroing out the remainder of the memory. This seems to be a wasteful effort. Perhaps it is enough to just null terminate the string?

int strncpy(char *dest, const char *src, size_t n) {
    size_t i = 0;
    while ((i++ &lt; n) &amp;&amp; (*dest++ = *src++));
    if (i &lt; n) {
        *dest = 0;
        return i;
    }
    return -1;
}