strverscmp -
2つのバージョン文字列を比較する
#define _GNU_SOURCE /* feature_test_macros(7) 参照 */
#include <string.h>
int strverscmp(const char *s1, const char *s2);
jan1,
jan2, ...,
jan9,
jan10, ...
といった名前のファイルがある状況はよくあるが、
ls(1) を実行したときに
jan1,
jan10, ...,
jan2, ...,
jan9
の順番で表示されるのには違和感がある。
これを修正するために、GNU
は
ls(1) に
-v
オプションを導入した。
この機能は
versionsort(3)
を使って実装されているが、この中で
strverscmp()
が使用されている。
このように
strverscmp()
の役目は2つの文字列を比較して「正しい」順序を探すことである。
これに対して
strcmp(3)
は辞書順だけで比較した結果を返す。
関数
strverscmp()
はロケールのカテゴリーである
LC_COLLATE を使用しない。
このことから、この関数が主にアスキー文字から成る文字列を
想定していることが分かる。
この関数の動作は以下の通りである。
両方の文字列が等しい場合、0
を返す。
それ以外の場合、その直前までは両方の文字列が等しく、
その直後のバイトで両者に違いがあるような、バイトの境界を探す。
見つかったバイト境界を含む数字列(数字だけの文字列)の最長一致検索を行う。
(数字列は境界から始まっていても、境界で終わっていてもよい)。
2つの文字列から得られた数字列の一方または両方が空であれば、
strcmp(3)
が返した結果を関数の返り値として返す。
すなわち、バイト値を比較した結果を返す。
それ以外の(数字列が両方とも空でない)場合、両方の数字列を数字順で比較する。
このとき、1つ以上の 0
が先頭にある数字列は、前に小数点がついているものと
解釈される。(先頭に 0
が多くある数字列ほど前に来ることになる)
この結果、順序は次のようになる:
000,
00,
01,
010,
09,
0,
1,
9,
10
関数
strverscmp()
は、ゼロよりも
1)小さい、2)等しい、3)大きいのいずれかの整数を返す。
それぞれは、
s1 が
s2
よりも、
1)小さい、2)等しい、3)大きい
ことを示す。
この節で使用されている用語の説明については、
attributes(7) を参照。
インターフェース |
属性 |
値 |
strverscmp() |
Thread safety |
MT-Safe |
この関数は GNU
による拡張である。
The program below can be used to demonstrate the behavior of
strverscmp(). It uses
strverscmp() to compare the two strings
given as its command-line arguments. An example of its use is the following:
$ ./a.out jan1 jan10
jan1 < jan10
#define _GNU_SOURCE
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
int
main(int argc, char *argv[])
{
int res;
if (argc != 3) {
fprintf(stderr, "Usage: %s <string1> <string2>\n", argv[0]);
exit(EXIT_FAILURE);
}
res = strverscmp(argv[1], argv[2]);
printf("%s %s %s\n", argv[1],
(res < 0) ? "<" : (res == 0) ? "==" : ">", argv[2]);
exit(EXIT_SUCCESS);
}
rename(1),
strcasecmp(3),
strcmp(3),
strcoll(3)
この man ページは Linux
man-pages
プロジェクトのリリース
5.10
の一部である。プロジェクトの説明とバグ報告に関する情報は
https://www.kernel.org/doc/man-pages/
に書かれている。