mycmp.c
von RobertDebiannutzer- SNIPPET_TEXT:
-
- #include <ctype.h>
- #include <limits.h>
- #include <locale.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #define ISDIGIT(c) (isdigit((unsigned char)(c)))
- static int digitcmp(char *buf1, char *buf2, size_t len1, size_t len2);
- static size_t get_digits(const char *str, char *buf);
- static int lettercmp(char *buf1, char *buf2, size_t i);
- static int mycmp(const char *s1, const char *s2);
- /* test functions */
- static int test_eq(const char *a, const char *b);
- static int test_lt(const char *a, const char *b);
- /* compares two digit sequences */
- int
- digitcmp(char *buf1, char *buf2, size_t len1, size_t len2)
- {
- size_t i, minlen;
- if (len1 == len2) {
- return strcmp(buf1, buf2);
- }
- /* get len of shorter number */
- minlen = len1 < len2 ? len1 : len2;
- /* skip leading zeros */
- while (*buf1 == '0' && *buf2 == '0') {
- buf1++;
- buf2++;
- }
- /* loop over equal digits */
- for (i=0; *buf1 == *buf2 && i<minlen; i++) {
- buf1++;
- buf2++;
- }
- /* if end of one number is reached, the other is greater */
- if (i == len1) {
- return -1;
- }
- if (i == len2) {
- return 1;
- }
- return *buf1-*buf2;
- }
- /* copy sequence of digits from str to buf and return number of copied digits */
- size_t
- get_digits(const char *str, char *buf)
- {
- const char *base = str;
- for (; ISDIGIT(*str); buf++, str++) {
- *buf = *str;
- }
- *buf = '\0';
- return str-base;
- }
- int
- lettercmp(char *buf1, char *buf2, size_t i)
- {
- buf1[i] = '\0';
- buf2[i] = '\0';
- return strcoll(buf1, buf2);
- }
- int
- mycmp(const char *s1, const char *s2)
- {
- char buf1[strlen(s1)+1], buf2[strlen(s2)+1];
- int r;
- size_t i, len1, len2;
- for (i=0; (*s1 != '\0') && (*s2 != '\0'); i++, s1++, s2++) {
- if (ISDIGIT(*s1) || ISDIGIT(*s2)) {
- if ((r = lettercmp(buf1, buf2, i)) != 0) {
- return r;
- }
- len1 = get_digits(s1, buf1);
- len2 = get_digits(s2, buf2);
- /* if not at position 0, digit > letter */
- if (len1 == 0 || len2 == 0) {
- return (i == 0) ? len2-len1 : len1-len2;
- }
- if ((r = digitcmp(buf1, buf2, len1, len2)) != 0) {
- return r;
- }
- s1 += len1;
- s2 += len2;
- i = 0;
- }
- buf1[i] = *s1;
- buf2[i] = *s2;
- }
- buf1[i] = *s1;
- buf2[i] = *s2;
- return lettercmp(buf1, buf2, i+1);
- }
- int
- test_eq(const char *a, const char *b)
- {
- return mycmp(a, b) != 0;
- }
- int
- test_lt(const char *a, const char *b)
- {
- return (mycmp(a, b) >= 0)
- + (mycmp(b, a) <= 0);
- }
- int
- main(int argc, char *argv[])
- {
- unsigned long long i;
- setlocale(LC_ALL, "de_DE.UTF-8");
- if (argc == 3) {
- printf("%d\n", mycmp(argv[1], argv[2]));
- exit(EXIT_SUCCESS);
- }
- if (argc == 2 && strcmp(argv[1], "--debug") == 0) {
- printf("%d\n%d\n%d\n%d\n%d\n%d\n%d\n%d\n",
- test_eq("", ""),
- test_lt("0", "1"),
- test_lt("1", "2"),
- test_lt("a", "b"),
- test_lt("abc-1.007.tgz", "abc-1.01a.tgz"),
- test_lt("abc-1.2.3.x86_64.rpm", "abc-1.2.3.4.x86_64.rpm"),
- test_lt("1file", "file1"),
- test_lt("abc-1.2.3.ä86_64.rpm", "abc-1.2.3.4.x86_64.rpm")
- );
- exit(EXIT_SUCCESS);
- }
- if (argc == 2 && strcmp(argv[1], "--perftest") == 0) {
- for (i=0; i<1000000; i++) {
- test_eq("", "");
- test_lt("0", "1");
- test_lt("1", "2");
- test_lt("a", "b");
- test_lt("abc-1.007.tgz", "abc-1.01a.tgz");
- test_lt("abc-1.2.3.x86_64.rpm", "abc-1.2.3.4.x86_64.rpm");
- test_lt("1file", "file1");
- test_lt("abc-1.2.3.ä86_64.rpm", "abc-1.2.3.4.x86_64.rpm");
- }
- exit(EXIT_SUCCESS);
- }
- if (argc == 1) {
- return
- + test_eq("", "")
- + test_lt("0", "1")
- + test_lt("1", "2")
- + test_lt("a", "b")
- + test_lt("abc-1.007.tgz", "abc-1.01a.tgz")
- + test_lt("abc-1.2.3.x86_64.rpm", "abc-1.2.3.4.x86_64.rpm")
- + test_lt("1file", "file1")
- + test_lt("abc-1.2.3.ä86_64.rpm", "abc-1.2.3.4.x86_64.rpm")
- ;
- }
- fprintf(stderr, "Usage: %s string1 string2\n"
- " or: %s\n"
- " or: %s --debug\n",
- argv[0], argv[0], argv[0]);
- exit(EXIT_FAILURE);
- }
Quellcode
Hier kannst du den Code kopieren und ihn in deinen bevorzugten Editor einfügen. PASTEBIN_DOWNLOAD_SNIPPET_EXPLAIN