strcat
tags: strcat, strcpy, string.h
The strcat
function allows you to join two strings by appending the second
string to the first, modifying the first string rather than creating a new one.
char *
strcat(char *s1, const char *s2);
It will return s1
which will now hold the concatenation of the two strings.
Implementation
To concatenate two strings means copying one to the end of the other. To find
the end of the first string we use the strlen
function to get an index for the
location of the terminating null character. Then we pass this location to
strcpy
, providing the second string as the second parameter.
strcpy(s1 + strlen(s1), s2);
return s1;
We don't need any parameter validation because strlen
and strcpy
do that for
us. If s1
is NULL
then strlen
will return 0 and we'll end up passing
NULL
to strcpy
which will return without modifying anything. Likewise, if
s2
is NULL
then strcpy
won't do anything.
Testing
We need to test concatenation to/from NULL
pointers, to/from empty strings,
and finally normal concatenation. In the case of NULL
pointers and an empty
source string, we expect the destination to be unmodified. Otherwise, we verify
that the result is the second string appended to the first.
int
strcatTest(void)
{
int ret = 1;
char *pStr1 = NULL;
char pStr2[15] = "hello, world";
char pStr3[15] = "hello, world";
char pStr4[15] = { 0 };
char pStr5[15] = "hello,";
char *pStr6 = " world";
do
{
/* Append to NULL, may crash */
strcat(pStr1, pStr2);
/* Concatenate from NULL, may crash */
strcat(pStr2, pStr1);
/* Concatenate to an empty string */
strcat(pStr4, pStr2);
if (0 != memcmp(pStr4, pStr2, strlen(pStr2)))
{
break;
}
/* Concatenate from an empty string */
memset(pStr4, '\0', sizeof(pStr4));
strcat(pStr2, pStr4);
if (0 != memcmp(pStr2, pStr3, sizeof(pStr3)))
{
break;
}
/* Normal concatenation */
strcat(pStr5, pStr6);
if (0 != memcmp(pStr5, pStr2, sizeof(pStr2)))
{
break;
}
ret = 0;
} while (0);
return ret;
}
Conclusion
As our library continues to grow, we'll find that more and more functions can be implemented in terms of existing functions. This will reduce the logic and validation required so that it becomes concentrated in certain parts of the library. It also means that there is less code to debug later on if there are any problems.
char *
strcat(char *s1, const char *s2)
{
strcpy(s1 + strlen(s1), s2);
return s1;
}