1

我目前正在编写一个小排序功能。我只能使用 stdio 库,所以我编写了我自己的 strcmp 函数。

int ownstrcmp(char a[], char b[])
{
   int i = 0;

   while( a[i] == b[i] )  
   {

      if( a[i] == '\0' ) 
        return 0;
      ++i;
   }

   return  ( a[i] < b[i]) ? 1 : -1;
}

这对我很有用。但是有一个小问题:我可以为“非标准字符”做什么?像 "ä,ü,ß 它们的十进制 ASCII 值大于普通字符,因此它对字符串 'example' 进行排序在 'ääää' 后面。我已经阅读了有关语言环境的信息,但我唯一可以使用的库是stdio.h。有吗这个问题的“简单”解决方案?

4

5 回答 5

1

您需要知道字符所在的编码,并确保正确处理字符串。如果编码是多字节的,您必须开始读取(和比较)单个字符,而不是字节。

此外,在国际上比较字符的方式因语言环境而异,没有单一的解决方案。在某些语言中,'ä' 排序在 'z' 之后,在某些语言中它紧挨着 'a' 排序。

实现这一点的一种简单方法当然是创建一个包含每个字符的相对顺序的表,如下所示:

unsigned char character_order[256];

character_order[(unsigned char) 'a'] = 1;
character_order[(unsigned char) 'ä'] = character_order[(unsigned char) 'a'];
/* ... and so on ... */

然后,不是减去字符的编码值(不再可以用作字符排序顺序的“代理”),而是比较这些character_order值。

以上假设是单字节编码,即Latin-1 之类的,因为数组大小只有256。

unsigned char还要注意使用字符文字索引时的强制转换。

于 2013-01-08T09:03:34.660 回答
1

你的问题有点含糊。首先,带有元音变音的字符如何表示取决于您的编码。例如,我的计算机的区域设置为希腊语,这意味着我用希腊字符代替了那些特殊的拉丁字符。据我所知,你不能假设这样的事情。

其次,您的问题的答案取决于您的陈述。您还在使用“char每个字符一个”表示吗?如果是这样,上面的代码可能仍然有效。

如果您使用多重char表示,例如char每个字符两个 s,您应该更改代码,以便在两个连续 char的 s 是时退出\0

通常,您可能想了解如何实现wchar_t及其功能系列(特别wcscmp是)。

于 2013-01-08T09:08:33.933 回答
1

对于德语,变音符号 ä,ö,ü 和 ß 将按照它们的“扩展”形式进行排序:

ä -> ae
ö -> oe
ü -> ue
ß -> ss

为了根据标准获得排序规则,您可以在比较之前扩展字符串。

于 2013-01-08T09:20:54.657 回答
0

如果您使用的是ISO/IEC_8859-16编码,这是德语的正常编码,那么将您转换charunsigned char.

这样,字符可以在 0-255 的区间内表示,适用于该标准。

于 2013-01-08T09:14:48.070 回答
0

在 UTF8 下,这可以提供帮助,遵循您的代码

if ((a[i] > 0) ^ (b[i] > 0))
    return a[i] > 0 ? 1 : -1;
else
    return a[i] < b[i] ? 1 : -1;

但是你必须检查像这样的案例ownstrcmp("ab", "abc");

strcmp()此外,您的代码不像<string.h>

大于零的值表示第一个不匹配的字符在 str1 中的值大于在 str2 中的值;小于零的值表示相反。

我会这样做:

int ownstrcmp(char a[], char b[])
{
    int i = 0;

    while(a[i] == b[i]) {
        if (a[i] == 0) return 0;
        ++i;
    }
    if ((a[i] == 0) || (b[i] == 0))
        return a[i] != 0 ? 1 : -1;
    if ((a[i] > 0) ^ (b[i] > 0))
        return a[i] < 0 ? 1 : -1;
    else
        return a[i] > b[i] ? 1 : -1;
}
于 2013-01-08T10:56:08.110 回答