Natural sort in C - “array of strings, containing numbers and letters”

后端 未结 4 815
被撕碎了的回忆
被撕碎了的回忆 2021-01-24 06:34

Looking for a proven to work algorithm for production. Did see this example but not finding much else on the web or in books.

i.e. file_10.txt > file_2.txt

Thank

4条回答
  •  生来不讨喜
    2021-01-24 07:17

    Here is a (tested) comparison function that does the job. It understands only unsigned integers, not signed integers or floating point:

    #include 
    #include 
    
    /* like strcmp but compare sequences of digits numerically */
    int strcmpbynum(const char *s1, const char *s2) {
      for (;;) {
        if (*s2 == '\0')
          return *s1 != '\0';
        else if (*s1 == '\0')
          return 1;
        else if (!(isdigit(*s1) && isdigit(*s2))) {
          if (*s1 != *s2)
            return (int)*s1 - (int)*s2;
          else
            (++s1, ++s2);
        } else {
          char *lim1, *lim2;
          unsigned long n1 = strtoul(s1, &lim1, 10);
          unsigned long n2 = strtoul(s2, &lim2, 10);
          if (n1 > n2)
            return 1;
          else if (n1 < n2)
            return -1;
          s1 = lim1;
          s2 = lim2;
        }
      }
    }
    

    If you want to use it with qsort, use this auxiliary function:

    static int compare(const void *p1, const void *p2) {
      const char * const *ps1 = p1;
      const char * const *ps2 = p2;
      return strcmpbynum(*ps1, *ps2);
    }
    

    And you can do something on the order of

    qsort(lines, next, sizeof(lines[0]), compare);
    

提交回复
热议问题