HiveBrain v1.2.0
Get Started
← Back to all entries
patterncMinor

Custom strcat() with different arguments

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
strcatargumentswithcustomdifferent

Problem

I am teaching myself C, and feel like I am just starting to get the hang of pointers and arrays (I come from Python, where everything is magic). I'm looking for reviews, especially if I'm doing anything wrong. In this code I wrote my own strcat() function, though it needs 3 args instead of the standard 2 (I couldn't figure out how to do it with just 2 without overrunning allotted memory).

#include 
#include 

char* cat(char *dest, char *a, char*b)
{   
    int len_a = strlen(a);
    int len_b = strlen(b);
    int i;
    for(i = 0; i < len_a; i++)
    {
        dest[i] = a[i];
    }
    puts("");
    int j;
    for(j = 0;j < len_b; i++, j++)
    {
        dest[i] = b[j];
    }
    dest[i] = '\0';
    puts("FUNCTION FINISHED");
}

int main()
{
    char strA[] = "I am a small ";
    char strB[] = "cat with whiskers.";
    char strC[strlen(strA) + strlen(strB) + 1];
    printf("length A: %lu, B: %lu, C: %lu\n", strlen(strA), strlen(strB), strlen(strC));
    printf("sizeof A: %lu, B: %lu, C: %lu\n", sizeof(strA), sizeof(strB), sizeof(strC));
    printf("A: '%s'\nB: '%s'\n", strA, strB);
    cat(strC, strA, strB);
    printf("c: '%s'\n", strC);
    printf("length A: %lu, B: %lu, C: %lu\n", strlen(strA), strlen(strB), strlen(strC));

    return 0;
}

Solution

char* cat(char *dest, char *a, char*b)


Interface critique: You should have the caller specify a maximum size for the destination buffer, and error out when there is not enough space. The mark of a good C programmer is to create interfaces which make this sort of condition unambiguous, rather than blasting away on the buffer, potentially past the allocation size.

for(i = 0; i < len_a; i++)
{
    dest[i] = a[i];
}


Strictly speaking this is fine, but it is rather un-C-like. I would prefer:

while (*a)
   *dest++ = *a++;


With this you do not need to call strlen, either.

Assuming you added the parameter you should add in my interface critique (let's call the new parameter destsz), you could make sure you don't write more than this size with something like:

int cat(char *dest, size_t destsz, const char *a, const char *b)
{
    while (*a && destsz)
    {
       *dest++ = *a++;
       --destsz;
    }

    while (*b && destsz)
    {
       *dest++ = *b++;
       --destsz;
    }

    if (!destsz)
       return -1; // ran out of buffer; error condition

    *dest = 0;   // we have space, so write NUL
    return 0;
}

Code Snippets

char* cat(char *dest, char *a, char*b)
for(i = 0; i < len_a; i++)
{
    dest[i] = a[i];
}
while (*a)
   *dest++ = *a++;
int cat(char *dest, size_t destsz, const char *a, const char *b)
{
    while (*a && destsz)
    {
       *dest++ = *a++;
       --destsz;
    }

    while (*b && destsz)
    {
       *dest++ = *b++;
       --destsz;
    }

    if (!destsz)
       return -1; // ran out of buffer; error condition

    *dest = 0;   // we have space, so write NUL
    return 0;
}

Context

StackExchange Code Review Q#13920, answer score: 5

Revisions (0)

No revisions yet.