bon*_*425 63 c string standard-library
我有两个char*我要比较的邮政编码,忽略了大小写.有这个功能吗?
或者我是否必须遍历每个使用tolower函数然后进行比较?
知道这个函数如何对字符串中的数字做出反应
谢谢
Fre*_*Foo 60
在C标准中没有这样做的功能.符合POSIX的Unix系统需要strcasecmp在标题中strings.h; 微软系统有stricmp.要在便携式方面,写下你自己的:
int strcicmp(char const *a, char const *b)
{
for (;; a++, b++) {
int d = tolower((unsigned char)*a) - tolower((unsigned char)*b);
if (d != 0 || !*a)
return d;
}
}
Run Code Online (Sandbox Code Playgroud)
但请注意,这些解决方案都不适用于UTF-8字符串,只能使用ASCII字符串.
Mih*_*yan 36
看看到strcasecmp()在strings.h.
比较小写还是大写?(足够常见的问题)
下面两个都将返回 0strcicmpL("A", "a")和strcicmpU("A", "a")。
然而,strcicmpL("A", "_")andstrcicmpU("A", "_")可以返回不同的签名结果,'_'通常在大写和小写字母之间。
这会影响与 一起使用时的排序顺序qsort(..., ..., ..., strcicmp)。非标准库 C 函数,如常用的 stricmp()或strcasecmp()倾向于定义良好的函数,并且倾向于通过小写字母进行比较。然而,变化是存在的。
int strcicmpL(char const *a, char const *b) {
while (*b) {
int d = tolower(*a) - tolower(*b);
if (d) {
return d;
}
a++;
b++;
}
return tolower(*a);
}
int strcicmpU(char const *a, char const *b) {
while (*b) {
int d = toupper(*a) - toupper(*b);
if (d) {
return d;
}
a++;
b++;
}
return toupper(*a);
}
Run Code Online (Sandbox Code Playgroud)
char可以有负值。(并不罕见)
touppper(int)和tolower(int)为unsigned charvalues 和负数指定EOF。此外,strcmp()返回结果就像每个都char被转换为unsigned char,无论char是signed还是unsigned。
tolower(*a); // Potential UB
tolower((unsigned char) *a); // Correct (Almost - see following)
Run Code Online (Sandbox Code Playgroud)
char可以有一个负值而不是 2 的补码。(稀有的)
由于-0位模式应解释为unsigned char. 要正确处理所有整数编码,请先更改指针类型。
// tolower((unsigned char) *a);
tolower(*(const unsigned char *)a); // Correct
Run Code Online (Sandbox Code Playgroud)
语言环境(不太常见)
尽管使用 ASCII 代码 (0-127) 的字符集无处不在,但其余代码往往具有特定于语言环境的问题。所以strcasecmp("\xE4", "a")可能在一个系统上返回 0,在另一个系统上返回非零。
Unicode(未来的方式)
如果解决方案需要处理的不仅仅是 ASCII,请考虑使用unicode_strcicmp(). 由于 C lib 不提供这样的函数,因此建议使用某个替代库中的预编码函数。编写自己的代码 unicode_strcicmp()是一项艰巨的任务。
所有字母都从低到高映射吗?(迂腐)
[AZ] 与 [az] 一对一映射,但各种语言环境将各种小写字符映射到一个大写字符,反之亦然。此外,某些大写字符可能缺少等效的小写字符,反之亦然。
这迫使代码通过tolower()和 进行转换tolower()。
int d = tolower(toupper(*a)) - tolower(toupper(*b));
Run Code Online (Sandbox Code Playgroud)
同样,如果代码tolower(toupper(*a))和toupper(tolower(*a)).
可移植性
@B。Nadolson建议避免自己滚动strcicmp(),这是合理的,除非代码需要高度等效的可移植功能。
下面是一种甚至比某些系统提供的函数执行得更快的方法。它通过使用 2 个不同的表对每个循环进行一次比较而不是两次比较'\0'。您的结果可能会有所不同。
static unsigned char low1[UCHAR_MAX + 1] = {
0, 1, 2, 3, ...
'@', 'a', 'b', 'c', ... 'z', `[`, ... // @ABC... Z[...
'`', 'a', 'b', 'c', ... 'z', `{`, ... // `abc... z{...
}
static unsigned char low2[UCHAR_MAX + 1] = {
// v--- Not zero, but A which matches none in `low1[]`
'A', 1, 2, 3, ...
'@', 'a', 'b', 'c', ... 'z', `[`, ...
'`', 'a', 'b', 'c', ... 'z', `{`, ...
}
int strcicmp_ch(char const *a, char const *b) {
// compare using tables that differ slightly.
while (low1[*(const unsigned char *)a] == low2[*(const unsigned char *)b]) {
a++;
b++;
}
// Either strings differ or null character detected.
// Perform subtraction using same table.
return (low1[*(const unsigned char *)a] - low1[*(const unsigned char *)b]);
}
Run Code Online (Sandbox Code Playgroud)
我发现内置的这样的方法名为from,其中包含标准标头中的其他字符串函数。
这是相关的签名:
int strcasecmp(const char *, const char *);
int strncasecmp(const char *, const char *, size_t);
Run Code Online (Sandbox Code Playgroud)
我还发现它是xnu内核(osfmk / device / subrs.c)的同义词,并在以下代码中实现,因此与原始的strcmp函数相比,您不会期望其行为发生任何变化。
tolower(unsigned char ch) {
if (ch >= 'A' && ch <= 'Z')
ch = 'a' + (ch - 'A');
return ch;
}
int strcasecmp(const char *s1, const char *s2) {
const unsigned char *us1 = (const u_char *)s1,
*us2 = (const u_char *)s2;
while (tolower(*us1) == tolower(*us2++))
if (*us1++ == '\0')
return (0);
return (tolower(*us1) - tolower(*--us2));
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
127346 次 |
| 最近记录: |