我怎样写一个合适的strcmp?
下面是我为strcmp编写的代码,我希望它不区分大写字母和小写字母,但是它仍然可以区分,如何解决这个问题我怎样写一个合适的strcmp?,c,C,下面是我为strcmp编写的代码,我希望它不区分大写字母和小写字母,但是它仍然可以区分,如何解决这个问题 int strcmp(char str1[], char str2[]) { int i = 0; for (; str1[i] || str2[i];) { if (str1[i] > str2[i]) { int j = (str1[i] - str2[i]); if (j == 32)
int strcmp(char str1[], char str2[]) {
int i = 0;
for (; str1[i] || str2[i];) {
if (str1[i] > str2[i]) {
int j = (str1[i] - str2[i]);
if (j == 32)
i++;
else {
return +1;
}
} else
if (str1[i] < str2[i]) {
int q = (str1[i] - str2[i]);
if (q == -32) {
i++;
} else {
return -1;
}
} else
if (str1[i] == str2[i]) {
i++;
}
}
return 0;
}
输出:
Aryan
Kim
Nap
Semi
kim
例如:
int strcasecmp(const char *a, const char *b)
{
size_t i;
for (i = 0; tolower((unsigned char)a[i]) == tolower((unsigned char)b[i]) && a[i]; ++i);
return tolower((unsigned char)a[i]) - tolower((unsigned char)b[i]);
}
例如:
int strcasecmp(const char *a, const char *b)
{
size_t i;
for (i = 0; tolower((unsigned char)a[i]) == tolower((unsigned char)b[i]) && a[i]; ++i);
return tolower((unsigned char)a[i]) - tolower((unsigned char)b[i]);
}
您的功能存在多个问题:
- 不要将名称命名为strcmp()。您不应该用不同的语义重新定义标准函数
通常是高度优化的,当您将strcmp()
传递给排序函数时,您的版本甚至可能不是使用的版本strcmp
- 该算法不正确:相隔32个位置的任意2个字符被视为相等,例如“0”==“p”
- 比较是不可传递的:您有
和“A”<“\u”
但是“A”
,这对于排序来说是非常有问题的“A”==“A”
- 您不应该假定ASCII和硬编码大小写偏移量。使用
中的
,并将toupper()
值转换为char
,以避免在负值上出现未定义的行为(无符号字符)
应该是i
size\u t
和str1
应为str2
合格const
#include <ctype.h>
int strcmp_case(const char *str1, const char *str2) {
for (size_t i = 0;; i++) {
int c1 = toupper((unsigned char)str1[i]);
int c2 = toupper((unsigned char)str2[i]);
if (c1 != c2) {
return (c1 > c2) - (c1 < c2);
}
if (c1 == '\0') {
return 0;
}
}
}
#包括
int strcmp_案例(常量字符*str1,常量字符*str2){
对于(大小i=0;i++){
int c1=toupper((无符号字符)str1[i]);
int c2=toupper((无符号字符)str2[i]);
如果(c1!=c2){
返回(c1>c2)-(c1
您的功能存在多个问题:
- 不要将名称命名为strcmp()。您不应该用不同的语义重新定义标准函数
通常是高度优化的,当您将strcmp()
传递给排序函数时,您的版本甚至可能不是使用的版本strcmp
- 该算法不正确:相隔32个位置的任意2个字符被视为相等,例如“0”==“p”
- 比较是不可传递的:您有
和“A”<“\u”
但是“A”
,这对于排序来说是非常有问题的“A”==“A”
- 您不应该假定ASCII和硬编码大小写偏移量。使用
中的
,并将toupper()
值转换为char
,以避免在负值上出现未定义的行为(无符号字符)
应该是i
size\u t
和str1
应为str2
合格const
#include <ctype.h>
int strcmp_case(const char *str1, const char *str2) {
for (size_t i = 0;; i++) {
int c1 = toupper((unsigned char)str1[i]);
int c2 = toupper((unsigned char)str2[i]);
if (c1 != c2) {
return (c1 > c2) - (c1 < c2);
}
if (c1 == '\0') {
return 0;
}
}
}
#包括
int strcmp_案例(常量字符*str1,常量字符*str2){
对于(大小i=0;i++){
int c1=toupper((无符号字符)str1[i]);
int c2=toupper((无符号字符)str2[i]);
如果(c1!=c2){
返回(c1>c2)-(c1
if((isalpha(str1[i])?tolower(str1[i]):str1[i])>等
如此多的分支…我建议你只使用toupper
或tolower
对每个字符进行比较,你能给出一些输入和输出的示例吗?我猜if(j==32)有点太天真了。请考虑<代码> 1代码> vs.代码> p>代码>这些都是相等的!<代码> ToupPu/COD>当字符不是小写字母时是良性的。所以只比较<代码> ToupPr(STR[i])< /> > <代码> ToupPr(STR2[i])
。不要使用像32
这样的幻数。在纯字符未签名的系统上,您的代码会失败得更糟。如果((isalpha(str1[i])?tolower(str1[i]):str1[i])>etc
如此多的分支…我建议您在每个字符上使用toupper
或tolower
,并进行比较。您能给出一些输入和输出的示例吗?我猜如果(j==32)有点太天真了。请考虑<代码> 1代码> vs.代码> p>代码>这些都是相等的!<代码> ToupPu/COD>当字符不是小写字母时是良性的。所以只比较<代码> ToupPr(STR[i])< /> > <代码> ToupPr(STR2[i])
。不要使用像32
这样的神奇数字。同样,在纯字符未签名的系统上,您的代码会失败得更糟。非常好,可移植性强。详细信息(可能超出OP的考虑范围):关键问题是在无大小写比较中,区域设置缺少小写字母到大写字母的映射。例如,迂腐的代码可以使用往返int c1=toupper(tolower((unsigned char)str1[i]);
或其近亲tolower(toupper())
。这两个函数的功能顺序倾向于将
的排序转移到字母之间。@chux:有趣的文章。应该注意的是,在对德语文本进行排序时,ß
应该扩展到ss
,这可能超出了OP的目标。对法语文本进行排序尤其困难,因为重音必须删除,但仍然存在我将从右到左考虑区分只在重音上不同的单词。无大小写比较的整个概念是语言/区域敏感的。当然,OP在这里的初始编码尝试是介绍性的,你的好答案将其提升到下一个层次。我只是希望我们大家都转向UTF8,使用库函数和由于粗心比较的详细信息非常广泛,所以不要使用通用的无大小写比较。虽然这种解决方案绝对正确,但看到布尔值上的算术运算让我感到不安。这会损害可读性,IMHO。@chux当然有很多选择。例如,return(c1>c2)?1:-1;
和c1-c2
在语义上是不正确的,顺便说一句(不管溢出情况如何)非常好而且非常便于携带。详细信息(可能超出OP的考虑):角落问题在案例中比较少