我目前正在编写一个小排序功能。我只能使用stdio libary,所以我写了'自己的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
。这个问题有一个“简单”的解决方案吗?
答案 0 :(得分: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
。
答案 1 :(得分:1)
你的问题有些模糊。首先,如何表示变音符号的字符取决于您的编码。例如,我的计算机的语言环境设置为希腊语,这意味着我用希腊字符代替那些特殊的拉丁字符。就我所知,你不能假设这样的事情。
其次,您的问题的答案取决于您的陈述。你还在使用“每个char
一个字符”吗?如果是这样,上面的代码可能仍然有用。
如果您使用多个char
表示形式,例如每个字符两个char
,则应更改代码,以便在连续两次 {{1 } {s}是char
。
通常,您可能希望了解\0
及其函数族(具体为wchar_t
)的实现方式。
答案 2 :(得分:1)
对于德语,变音符号ä,ö,ü和ß将按其“扩展”形式进行排序:
ä -> ae
ö -> oe
ü -> ue
ß -> ss
为了根据标准获得排序规则,您可以在比较之前扩展字符串。
答案 3 :(得分:0)
如果您使用的是ISO/IEC_8859-16编码,这是德语的正常加入,那么将char
转换为unsigned char
就足够了。
这样,字符可以在区间0-255中表示,适用于此标准。
答案 4 :(得分: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;
}