C语言中strcmp()函数的实现

7

我需要自己制作一个strcmp函数,使用指针操作。以下是我的代码:

int mystrcmp(const char *str1, const char *str2) {
    while ('\0' != *str1 && *str1 == *str2) {
        str1 += 1;
        str2++;
    }
    int result1 = (uint8_t)(*str2) - (uint8_t)(*str1); // I need (uint8_t) to use it with Russian symbols.
    return result1;
}

但是我的导师告诉我,我的代码中有一些小错误。我花了很多时间进行测试,但是无法找到它。


4
为什么你在使用 str1 += 1 而不是 str2++?同时,你没有检查 str2 是否比 str1 短。 - Eli Sadoff
1
请不要更改代码:您的实际代码str1++还是str1 += 1 - Weather Vane
3
写下4个基本测试用例。比较相同的字符串;长度相同但文本不同的字符串;str1比str2长的字符串;str2比str1长的字符串。在代码中运行每个测试用例并检查结果。通过测试你的代码,你会很快发现错误,并成为一个更好的程序员。 - abelenky
2
说实话,我在这里找不到任何错误。仔细查看了这段代码后,我没有发现任何错误或无用的部分。可能是你的导师错了,或者他在谈论代码的另一部分。 - Dellowar
1
你的结果符号与正常情况相反,是吗?uint8_t 强制转换没问题;它将可能带符号的 char 值强制转换为正的 uint8_t 值,然后在减法运算之前提升为 int(正常类型提升)。但如果 str1 中不同的字符是 'a',而 str2 中是 'b',则应该返回负值,但你会返回正值。 - Jonathan Leffler
显示剩余8条评论
2个回答

9
这回答了你做错了什么的问题吗?
#include <stdio.h>
#include <stdint.h> 
#include <string.h>

int mystrcmp(const char *str1, const char *str2);

int main(void)
{
    char* javascript = "JavaScript";
    char* java = "Java";

    printf("%d\n", mystrcmp(javascript, java));
    printf("%d\n", strcmp(javascript, java));
    return 0;
}

int mystrcmp(const char *str1, const char *str2) {
    while ('\0' != *str1 && *str1 == *str2) {
        str1 += 1;
        str2++;
    }
    int result1 = (uint8_t)(*str2) - (uint8_t)(*str1); // I need (uint8_t) to use it with Russian symbols.
    return result1;
}

输出:

-83
 83

I'll propose a quick fix:

Change

int result1 = (uint8_t)(*str2) - (uint8_t)(*str1);

To

int result1 =  (uint8_t)(*str1) - (uint8_t)(*str2);

你错在哪里:

strcmp()的返回值应该是:

如果返回值小于0,则表示str1小于str2。

如果返回值大于0,则表示str2小于str1。

如果返回值等于0,则表示str1等于str2。

而你却完全相反。


5

@yLaguardia很好地解决了订单问题。

int strcmp(const char *s1, const char *s2);

strcmp函数返回一个整数,如果s1指向的字符串大于s2指向的字符串,则返回大于零的整数;如果相等,则返回零;如果小于,则返回小于零的整数。C11dr §7.24.4.2 3


在绝大多数情况下,使用uint8_t是可以的。很少有机器不使用8位的char,所以uint8_t不可用。无论如何,由于unsigned char处理所需的unsigned比较,因此它是不必要的。(关于无符号比较,请参见下文。)

int result1 = 
    ((unsigned char)*str1 - (unsigned char)*str2);

即使更高级的可移植代码也会使用以下方法来处理当char范围和unsigned范围匹配以及所有其他char,unsigned char,int,unsigned大小/范围。
int result1 = 
    ((unsigned char)*str1 > (unsigned char)*str2) - 
    ((unsigned char)*str1 < (unsigned char)*str2);

strcmp()函数将每个字符视为无符号字符,而不管char是带符号的还是无符号的。

...... 每个字符应被解释为具有unsigned char类型......C11 §7.24.1 3

char是否为ASCII编码与strcmp()的编码无关。当然,在不同的字符编码下,可能会得到不同的结果。例如:strcmp("A", "a")在一种编码中可能导致正答案(很少使用的EBCDIC),但在另一种编码中为负答案(ASCII)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接