Я на самом деле не фанат ответа с наибольшим количеством голосов здесь (отчасти потому, что он неправильный, так как он должен продолжаться, если он читает нулевой терминатор в любой строке - но не обаСтруны сразу - и это не делает этого), поэтому я написал свой собственный.
Это прямая замена для strncmp()
, которая была полностью протестирована с многочисленными тестами, как показано ниже:
Кодтолько:
#include <ctype.h> // for `tolower()`
#include <limits.h> // for `INT_MIN`
// Case-insensitive `strncmp()`
static inline int strncmpci(const char * str1, const char * str2, size_t num)
{
int ret_code = INT_MIN;
size_t chars_compared = 0;
if (!str1 || !str2)
{
goto done;
}
while ((*str1 || *str2) && (chars_compared < num))
{
ret_code = tolower((int)(*str1)) - tolower((int)(*str2));
if (ret_code != 0)
{
break;
}
chars_compared++;
str1++;
str2++;
}
done:
return ret_code;
}
Версия с полным комментариями:
#include <ctype.h> // for `tolower()`
#include <limits.h> // for `INT_MIN`
/*
Case-insensitive string compare (strncmp case-insensitive)
- Identical to strncmp except case-insensitive. See: http://www.cplusplus.com/reference/cstring/strncmp/
- Aided/inspired, in part, by: https://stackoverflow.com/a/5820991/4561887
str1 C string 1 to be compared
str2 C string 2 to be compared
num max number of chars to compare
return:
(essentially identical to strncmp)
INT_MIN invalid arguments (one or both of the input strings is a NULL pointer)
<0 the first character that does not match has a lower value in str1 than in str2
0 the contents of both strings are equal
>0 the first character that does not match has a greater value in str1 than in str2
*/
static inline int strncmpci(const char * str1, const char * str2, size_t num)
{
int ret_code = INT_MIN;
size_t chars_compared = 0;
// Check for NULL pointers
if (!str1 || !str2)
{
goto done;
}
// Continue doing case-insensitive comparisons, one-character-at-a-time, of str1 to str2,
// as long as at least one of the strings still has more characters in it, and we have
// not yet compared num chars.
while ((*str1 || *str2) && (chars_compared < num))
{
ret_code = tolower((int)(*str1)) - tolower((int)(*str2));
if (ret_code != 0)
{
// The 2 chars just compared don't match
break;
}
chars_compared++;
str1++;
str2++;
}
done:
return ret_code;
}
int main()
{
printf("Hello World\n\n");
const char * str1;
const char * str2;
size_t n;
str1 = "hey";
str2 = "HEY";
n = 3;
printf("strncmpci(%s, %s, %u) = %i\n", str1, str2, n, strncmpci(str1, str2, n));
printf("strncmp(%s, %s, %u) = %i\n", str1, str2, n, strncmp(str1, str2, n));
printf("\n");
str1 = "heY";
str2 = "HeY";
n = 3;
printf("strncmpci(%s, %s, %u) = %i\n", str1, str2, n, strncmpci(str1, str2, n));
printf("strncmp(%s, %s, %u) = %i\n", str1, str2, n, strncmp(str1, str2, n));
printf("\n");
str1 = "hey";
str2 = "HEdY";
n = 3;
printf("strncmpci(%s, %s, %u) = %i\n", str1, str2, n, strncmpci(str1, str2, n));
printf("strncmp(%s, %s, %u) = %i\n", str1, str2, n, strncmp(str1, str2, n));
printf("\n");
str1 = "heY";
str2 = "HeYd";
n = 3;
printf("strncmpci(%s, %s, %u) = %i\n", str1, str2, n, strncmpci(str1, str2, n));
printf("strncmp(%s, %s, %u) = %i\n", str1, str2, n, strncmp(str1, str2, n));
printf("\n");
str1 = "heY";
str2 = "HeYd";
n = 6;
printf("strncmpci(%s, %s, %u) = %i\n", str1, str2, n, strncmpci(str1, str2, n));
printf("strncmp(%s, %s, %u) = %i\n", str1, str2, n, strncmp(str1, str2, n));
printf("\n");
str1 = "hey";
str2 = "hey";
n = 6;
printf("strncmpci(%s, %s, %u) = %i\n", str1, str2, n, strncmpci(str1, str2, n));
printf("strncmp(%s, %s, %u) = %i\n", str1, str2, n, strncmp(str1, str2, n));
printf("\n");
str1 = "hey";
str2 = "heyd";
n = 6;
printf("strncmpci(%s, %s, %u) = %i\n", str1, str2, n, strncmpci(str1, str2, n));
printf("strncmp(%s, %s, %u) = %i\n", str1, str2, n, strncmp(str1, str2, n));
printf("\n");
str1 = "hey";
str2 = "heyd";
n = 3;
printf("strncmpci(%s, %s, %u) = %i\n", str1, str2, n, strncmpci(str1, str2, n));
printf("strncmp(%s, %s, %u) = %i\n", str1, str2, n, strncmp(str1, str2, n));
printf("\n");
return 0;
}
Пример вывода:
Hello World
strncmpci (hey, HEY, 3) = 0
strncmp (hey, HEY, 3) = 32
strncmpci (heY, HeY, 3) = 0
strncmp (heY, HeY, 3) = 32
strncmpci (hey, HEdY, 3) = 21
strncmp (эй, HEdY, 3) = 32
strncmpci (heY, HeYd, 3) = 0
strncmp (heY, HeYd, 3) = 32
strncmpci (heY, HeYd, 6)= -100
strncmp (heY, HeYd, 6) = 32
strncmpci (hey, hey, 6) = 0
strncmp (hey, hey, 6) = 0
strncmpci (хей, хейд, 6) = -100
strncmp (хей, хейд, 6) = -100
strncmpci (хей, хейд, 3) = 0
strncmp (хей, хейд, 3) = 0
Ссылки:
- Этот вопрос и другие ответы здесь послужили источником вдохновения и дали некоторое представление ( Компонент без учета регистра в C )
- http://www.cplusplus.com/reference/cstring/strncmp/
- https://en.wikipedia.org/wiki/ASCII
- https://en.cppreference.com/w/c/language/operator_precedence