views:

208

answers:

2

I know that strcat (dest, src) appends src to dest, and returns dest. Now, if I want to append dest, to src. i.e. insert string "src" before dest, is their any way to do that?

I tried using strcat something like

dest = strcat (dest, src);

but could not make it work.

PS: I am trying out a few options. As this this solution is needed urgently I thought of asking this question to the list.

+3  A: 

If you want to do this without modifying src, you could do it in two steps:

strcpy(temp, src);
strcat(temp, dest);

All error handling, and determination of a sufficiently large size for temp, has been omitted in the interest of clarity.

Greg Hewgill
And for completeness, to do this without a `temp` would be `size = strlen(src); memmove(dest + size, dest, size); strcpy(dest, src);` (roughly - I'd use `memcpy()` for the second but it's all relative or something)
Chris Lutz
@Chris: Maybe `size = strlen(src); memmove(dest+size, dest, strlen(dest)+1); memcpy(dest, src, size);`
Michael Burr
+2  A: 

Here's a lightly tested implementation of strlprecat() which more or less follows OpenBSD's 'strlxxx()' function style of:

  • passing a length for the destination buffer,
  • always terminating the resulting string (if the buffer size is greater than 0) and
  • returning the length of the buffer required (not including the terminator character)

So this function will never result in a buffer overrun, but may result in a truncated string (destroying the original string in the buffer as a consequence).

Anyway, I've found a similar function to be occasionally useful:

size_t
strlprecat( char* dst, const char * src, size_t size)
{
    size_t dstlen = strnlen( dst, size);
    size_t srclen = strlen( src);
    size_t srcChars = srclen;
    size_t dstChars = dstlen;

    if (0 == size) {
        /* we can't write anything into the dst buffer */
        /*  -- bail out                                */

        return( srclen + dstlen);
    }

    /* determine how much space we need to add to front of dst */

    if (srcChars >= size) {
        /* we can't even fit all of src into dst */
         srcChars = size - 1;
    }

    /* now figure out how many of dst's characters will fit in the remaining buffer */
    if ((srcChars + dstChars) >= size) {
        dstChars = size - srcChars - 1;
    }

    /* move dst to new location, truncating if necessary */
    memmove( dst+srcChars, dst, dstChars);

    /* copy src into the spot we just made for it */
    memcpy( dst, src, srcChars);

    /* make sure the whole thing is terminated properly */
    dst[srcChars + dstChars] = '\0';

    return( srclen + dstlen);
}

Feel free to muck with this so it doesn't deal with a buffer length (blindly moves stuff to the desired place) or simply returns an error without doing anything if the buffer's not large enough.

Oh, and of course post a comment if you fix any bugs.

Michael Burr
To pick a nit, it's not legal in C to define a function whose name starts with "str" followed by a letter. That's sort of a reserved namespace for the standard library. http://c-faq.com/decl/namespace.html is a good reference for these things.
unwind
I'm aware that I'm living dangerously, but I'm curiously unconcerned; remember, I stole the naming convention from OpenBSD (watch my boldness bite me in the ass when C2018 comes out). But anyone is free to change the name if it doesn't suit them.
Michael Burr