基本上我有一个字符串数组,我需要检查它们是否按字典顺序排列(大小写不敏感,这意味着它是哪个无关紧要)。为此,我使用已经创建的strcmp函数并重新排列它,以便它是大写还是小写都无关紧要。但是当输入str_compare时,它不会进入while循环,而只是退出函数。有人知道为什么吗?下面是代码:
int main(){
...
char * banned_words[N];
...
if (!are_sorted(banned_words, n)) {
printf("Words are not sorted correctly!n");
free_strings(banned_words, n);
return ERROR;
}
...
}
bool are_sorted(char * strings[], int n) {
int length = n;
int result = 0;
for (int i = 0; i < length - 1; i++) {
result += str_compare(strings[i], strings[i + 1]);
}
if (result > 0)
return false;
else
return true;
}
int str_compare(char **str1, char **str2){
while (str1 && str2) {
if (str1 >= 'A' && str1 <='Z' && (str1 + 'a' - 'A') == str2){
**str1++;
**str2++;}
else if (str2 >= 'A' && str2<='Z' && (str2 + 'a' - 'A') == str1){
**str1++;
**str2++;}
else if (str1 == *str2){
**str1++;
**str2++;}
else break;
}
if (str1 >= 'A' && str1<='Z')
return (str1 +'a' - 'A') - str2;
else if (str2 >= 'A' && str2<='Z')
return str1 - (str2 +'a'-'A');
else return str1 - str2;
}
使用char *
类型的表达式调用函数str_compare
result += str_compare(strings[i], strings[i + 1]);
功能参数类型为char **
。
int str_compare(char **str1, char **str2){
这个while循环
while (str1 && str2)
调用未定义的行为,因为当至少一个指针变为空指针时,循环的条件计算为false。
同样在if语句中的函数条件中,例如
if (str1 >= 'A' && str1 <='Z' && (str1 + 'a' - 'A') == str2){
或
else if (str1 == *str2){
没有意义。比较操作数的类型不同
还有这个代码片段中的return语句
if (str1 >= 'A' && str1<='Z')
return (str1 +'a' - 'A') - str2;
else if (str2 >= 'A' && str2<='Z')
return str1 - (str2 +'a'-'A');
else return str1 - str2;
可以产生不可预测的结果。
函数are_sorted
for (int i = 0; i < length - 1; i++) {
result += str_compare(strings[i], strings[i + 1]);
}
if (result > 0)
return false;
else
return true;
实际上并不决定字符串数组是否已排序。例如,一对字符串的比较可以产生-1
,而另一对字符串的比较可以产生1
,结果将等于0
,尽管数组没有排序。
函数str_compare
可以如下面的示例程序所示定义:
#include <stdio.h>
#include <ctype.h>
int str_compare( const char *s1, const char *s2 )
{
char c1 = ' ', c2 = ' ';
while ( *s1 && ( c1 = tolower( ( unsigned char )*s1 ) ) == ( c2 = tolower( ( unsigned char) *s2 ) ) )
{
++s1;
++s2;
}
return islower( ( unsigned char )*s1 ) && islower( ( unsigned char ) *s2 )
? c1 - c2
: *s1 - *s2;
}
int main(void)
{
const char *s1 = "HeLlO";
const char *s2 = "hElLo";
printf( ""%s" == "%s" is %d", s1, s2, str_compare( s1, s2 ) );
return 0;
}
程序输出为
"HeLlO" == "hElLo" is 0
如果您可能不使用标准的C函数tolower
,那么函数str_compare
可以如下所示
int str_compare( const char *s1, const char *s2 )
{
char c1 = ' ', c2 = ' ';
while ( 1 )
{
c1 = *s1; c2 = *s2;
if ( 'A' <= c1 && c1 <= 'Z' ) c1 += 'a' - 'A';
if ( 'A' <= c2 && c2 <= 'Z' ) c2 += 'a' - 'A';
if ( c1 != c2 || c1 == ' ' ) break;
++s1; ++s2;
}
return 'a' <= c1 && c1 <= 'z' && 'a' <= c2 && c2 <= 'z'
? c1 - c2 : *s1 - *s2;
}
对于函数are_sorted
,它可以这样定义
bool are_sorted( char * strings[], size_t n )
{
size_t i = n;
if ( n != 0 )
{
++i;
while ( i != n && str_compare( strings[i-1], strings[i] ) <= 0 ) ++i;
}
return i == n ;
}