Coding a Better stringcopy() Function

From last week’s Lesson, the task is to code a safer, better version of the strcpy() function. The goals are to check buffer size, report an overflow or underflow (buffer is too big or too small), and potentially confirm whether data is overwritten. Such a program is often used as a test when applying for a C programming job.

My solution is the stringcopy() function with this prototype:

int stringcopy(char *dest, size_t dsize, const char *src, size_t ssize)

This function uses two arguments found in strcpy(): the address of the string to copy, pointer src, and the address of the buffer where the string is to be copied, pointer dest. Two additional arguments are the size of each buffer: dsize for the destination buffer’s size and ssize for the source buffer’s size. This approach parallels the many alternative, or “safe,” strcpy() function variations.

I’ve also added a return value to my stringcopy() function. The value is negative for an overflow, meaning that not every character is copied. It’s positive for an underflow, meaning that unused space (or characters) remain in the destination buffer. The return value is zero when both buffers match.

Here is my code:

2025_10_04-Lesson.c

#include <stdio.h>

/* arguments determine buffer sizes
   return value:
   negative for overflow, chars cut
   positive for underflow, chars left in the buffer
   zero for a perfect copy, no wasted space
 */
int stringcopy(char *dest, size_t dsize, const char *src, size_t ssize)
{
    int flow,x;

    /* test the buffer fit */
    flow = dsize-ssize;

    /* if overflow, copy only dsize characters */
    if( flow<0 )
    {
        for( x=0; x<dsize-1; x++ )
            *(dest+x) = *(src+x);
        *(dest+x) = '\0';
    }
    /* if underflow, copy the entire string */
    /* same condition apples to equal buffer size */
    else
    {
        for( x=0; x<ssize; x++ )
            *(dest+x) = *(src+x);
        *(dest+x) = '\0';
    }

    return(flow);
}

int main()
{
    const char size=16;
    char dest[size];
    char src[] = "The string is the thing";
    int r;

    /* copy the string */
    r = stringcopy(dest,size,src,sizeof(src)-1);
    /* test result */
    if( r<0 )
    {
        puts("String overflow");
        printf("'%s' copied to '%s'\n",src,dest);
    }
    else if( r>0 )
    {
        puts("String underflow");
        printf("'%s' copied to '%s'\n",src,dest);
    }
    else
    {
        puts("String fully copied");
        printf("'%s' copied to '%s'\n",src,dest);
    }

    return 0;
}

The stringcopy() function first calculates integer variable flow as the difference between the destination buffer’s size and the source buffer’s size. The result determines overflow or underflow.

An if-else decision is made depending on the value of flow. When flow is less than zero, meaning that the buffer would otherwise overflow, only dsize-1 characters are copied into buffer dest. The final character is the null character, creating the string.

The else condition handles underflow, in which case the entire string is copied. This condition also handles when the dest buffer is larger than necessary, with flow containing the number of characters remaining in the buffer.

No matter which decision is made, the value of flow is returned, indicating underflow or overflow as well as reporting characters cut off or remaining in the buffer.

The main() function copies a source string that’s too long to fit in the destination buffer. Variable r captures the return value from the stringcopy() function, with an if else-if else structure handling the various conditions possible.

Here’s output from a sample run:

String overflow
'The string is the thing' copied to 'The string is t'

I’m not certain whether this code will land me a job, but it doesn’t accomplish the task at hand. In the future I may explore the variety of string copying functions and how they deal with various conditions. Just about anything is better than the standard strcpy() function, which can easily be exploited.

Leave a Reply