strncmp
tags: memcmp, string.h, strlen, strncmp
The strncmp
function allows you to compare to strings to determine their
(in)equality while also specifying a maximum number of characters to compare.
int
strncmp(const char *s1, const char *s2, size_t n);
The return value is an integer which indicates whether the first string is greater than, equal to, or less than the second string.
Implementation
strncmp
is of course similar to strcmp
, but we first need to determine how
many characters should be compared, as any characters after a null-character in
s1
should not be compared. Therefore, we need to determine the length of s1
,
plus 1 for the null-character, and compare a number of characters which is the
lesser of that value and n
. We can then pass the real work on to memcmp
.
size_t len1 = strlen(s1) + 1;
if (len1 < n)
{
n = len1;
}
return memcmp(s1, s2, n);
It's important to include the + 1
as otherwise an s1
which is a substring of
s2
would compare as equal (e.g. strncmp("foo", "foobar", strlen("foobar"))
).
Testing
We need to test comparison to/from NULL
pointers, to/from empty strings,
and all cases of equal, greater than, and less than results. The only deviation
from the strcmp
tests is comparing two strings where one is a substring of the
other. Performing this test ensures that the null-character is accounted for
when s1
is shorter than s2
.
int
strncmpTest(void)
{
int ret = 1;
char pStr1[] = "This is a Test string";
char pStr2[] = "This is a Test string";
char pStr3[] = "This is a Lesser string";
char pStr4[] = "This is a greater string";
char *pStr5 = NULL;
char pStr6[] = "This is a Test string with more";
do
{
/* NULL s2 pointer */
if (1 != strncmp(pStr1, pStr5, sizeof(pStr1)))
{
break;
}
/* NULL s1 pointer */
if (1 != strncmp(pStr5, pStr1, sizeof(pStr1)))
{
break;
}
/* Empty s2 */
if (0 >= strncmp(pStr1, "", sizeof(pStr1)))
{
break;
}
/* Empty s1 */
if (0 <= strncmp("", pStr1, sizeof(pStr1)))
{
break;
}
/* Test equality */
if (0 != strncmp(pStr1, pStr2, sizeof(pStr1)))
{
break;
}
/* Test equal substrings */
if (0 != strncmp(pStr1, pStr6, sizeof(pStr1) - 1))
{
break;
}
/* Test inequal strings */
if (0 == strncmp(pStr1, pStr6, sizeof(pStr1)))
{
break;
}
/* First string greater than second string */
if (0 >= strncmp(pStr1, pStr3, sizeof(pStr1)))
{
break;
}
/* First string less than second string */
if (0 <= strncmp(pStr1, pStr4, sizeof(pStr1)))
{
break;
}
ret = 0;
} while (0);
return ret;
}
Conclusion
Again, memcmp
does all the work and we need to take care when calculating the
maximum number of characters to be compared.
int
strncmp(const char *s1, const char *s2, size_t n)
{
size_t len1 = strlen(s1) + 1;
if (len1 < n)
{
n = len1;
}
return memcmp(s1, s2, n);
}