Home > Back-end >  How can I compare numerical strings in C?
How can I compare numerical strings in C?

Time:10-17

I was having an issue in my program when comparing two numerical strings. I'm using strcmp right now but when comparing it thinks that 4 > 24 since it's comparing the first character. Is there a different way of comparing two numerical strings?

Note: My string can't contain a negative number!

Example of string I'm trying to compare:

"4 HelloWorld", 
"24 HelloWorld2"

I want the second string the be bigger since 24>4

Here's an example of the code I'm trying to solve:

int sort_string(const void *string1, const void *string2)
{
    char *const *p1 = string1;
    char *const *p2 = string2;
    return strcmp(*p2, *p1);
}

CodePudding user response:

I don't know if this fits into your requirements, but you can use feature of atoi() that it stops to convert string after first non-numeric character. Also it ignores leading spaces.

#include <stdlib.h>
#include <stdio.h>

int sort_string(const void *a, const void *b)
{
    return atoi(*(const char **)a) - atoi(*(const char **)b);
}

int main(void)
{
    const char *text[] = {
        "24 HelloWorld2",
        "4 HelloWorld",
        " 50 HelloWorld3",
        "1 HelloWorld4",
        "100 HelloWorld5",
    };

    qsort(text, 
          sizeof(text)/sizeof(*text),
          sizeof(*text),
          sort_string);

    for (size_t i = 0; i < sizeof(text)/sizeof(*text);   i)
    {
        printf("%s\n", text[i]);
    }

    return 0;
}

Output:

1 HelloWorld4
4 HelloWorld
24 HelloWorld2
 50 HelloWorld3
100 HelloWorld5

CodePudding user response:

If the data conforms to the samples provided - always positive digit sequence followed by non-digit (and then maybe more stuff):

char *p1 = strchr( str1, ' ' );
char *p2 = strchr( str2, ' ' );
if( p1 && p2 && (res = (p1-str1) - (p2-str2) ) == 0 )
    res = strcmp( str1, str2 );
return res;

The "longer" string of digits will represent the larger base10 value.

If the single option of a 'space' is too limited, strspn( strX, "0123456789" ); could be used instead.

(Note: this method is not restricted to the finite number of bits available datatypes of unsigned int, or unsigned long long. Note, too, that this method, allowing, for instance, "ABCDEF" would also work for (single case) hexadecimal values, and, allowing "." could be extended to work for left justified floating point values where "42.70" would be regarded as less than "420.7", as it should be, without conversion to a built-in datatype.)

Caveat: 4 is expressed as 4, not 0000000004... Depends on the data, naturally...

Although it seems trivial, converting base 10 to base 2 may be expensive in terms of execution time.

  •  Tags:  
  • c
  • Related