1
\$\begingroup\$

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++ < n) && (*d++ = *src++));
    while (i++ < 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 < size_d) && (*d++ = *src++)) i++;
    if (i < size_d)//everything copied.
    {
        if (i < 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 > size_d, impossible.
    }
    return dest;
} 
\$\endgroup\$
  • 1
    \$\begingroup\$ Why are you writing C-like code when working with C++? What functionality do you want to achieve what you wouldn't get from using std::string and it's functionalities? \$\endgroup\$ – zxcdw Jun 25 '12 at 13:08
  • \$\begingroup\$ @zxcdw just for practicing. \$\endgroup\$ – upton Jun 25 '12 at 15:25
  • 1
    \$\begingroup\$ @upton, perhaps you should consider removing c++ tag? c++ is a very different language with emphasis on different idioms, and your code may not get enough traction from c programmers if you indicate that c++ is involved. Conversely, you might get flamed for writing c like code in c++ if you claim it to be good c++ code. \$\endgroup\$ – rahul Jun 26 '12 at 20:57
1
\$\begingroup\$

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++ < n) && (*dest++ = *src++));
    if (i < n) {
        *dest = 0;
        return i;
    }
    return -1;
}
\$\endgroup\$
-1
\$\begingroup\$

This would be my solution:

#include <string>
#include <iostream>

int main() {
    // C++, so use what it provides you. A relatively flexible string library.
    std::string a = "Hello ";
    std::string b = "World!";
    std::string c;

    // easy, simple, reliable, safe and FAST string copying and concatenation!
    c = a + b;

    std::cout << c << std::endl;

    return 0;
}

After all, since you are working with C++, take advantage of what it offers you. Writing C is outright dumb unless you have a reason to do so, as it gives you no benefits at all. It's not secure, it's slow, it's complex and bug prone.

If your code works, what makes you think "it could be much better"? What is better than working code? The thing is, that if it works don't fix it.

\$\endgroup\$
  • \$\begingroup\$ "What is better than working code?" How about working, maintainable code? \$\endgroup\$ – Benjamin Kloster Jun 25 '12 at 15:54
  • \$\begingroup\$ @BenjaminKloster yes and robust code and fast code and elegant code and whatnot. However, the bottom line is that if it works, don't try to fix it "just because". The fact that something works is far, far more important than the rest. If something is broken, it is useless. You get what I mean. ;) \$\endgroup\$ – zxcdw Jun 25 '12 at 16:55
  • \$\begingroup\$ @zxcdw This is codereview, not if-it-works-dont-fix-it.stackeexchange. \$\endgroup\$ – Corbin Jun 27 '12 at 15:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.