I decided to share the method I came up with:

    /**
     * Compares two strings, ignoring the case of ASCII characters. It treats
     * non-ASCII characters taking in account case differences. This is an 
     * attempt to mimic glib's string utility function 
     * <a href="http://developer.gnome.org/glib/2.28/glib-String-Utility-Functions.html#g-ascii-strcasecmp">g_ascii_strcasecmp ()</a>.
     *
     * This is a slightly modified version of java.lang.String.CASE_INSENSITIVE_ORDER.compare(String s1, String s2) method.
     * 
     * @param str1  string to compare with str2
     * @param str2  string to compare with str1
     * @return      0 if the strings match, a negative value if str1 < str2, or a positive value if str1 > str2
     */
    private static int compareToIgnoreCaseASCIIOnly(String str1, String str2) {
        int n1 = str1.length();
        int n2 = str2.length();
        int min = Math.min(n1, n2);
        for (int i = 0; i < min; i++) {
            char c1 = str1.charAt(i);
            char c2 = str2.charAt(i);
            if (c1 != c2) {
                if ((int) c1 > 127 || (int) c2 > 127) { //if non-ASCII char
                    return c1 - c2;
                } else {
                    c1 = Character.toUpperCase(c1);
                    c2 = Character.toUpperCase(c2);
                    if(c1 != c2) {
                        c1 = Character.toLowerCase(c1);
                        c2 = Character.toLowerCase(c2);
                        if(c1 != c2) {
                            return c1 - c2;
                        }
                    }
                }
            }
        }
        return n1 - n2;
    }
Answer from bancer on Stack Overflow
🌐
Oracle
docs.oracle.com › cd › E19146-01 › 821-0787 › abvlv › index.html
util_strcasecmp() Function (Sun Java System Web Server 7.0 Update 7 NSAPI Developer's Guide)
Sun Java System Web Server 7.0 Update 7 NSAPI Developer's Guide ... The util_strcasecmp function performs a comparison of two alphanumeric strings and returns a -1, 0, or 1 to signal which string is larger or the strings are identical.
Top answer
1 of 2
1

I decided to share the method I came up with:

    /**
     * Compares two strings, ignoring the case of ASCII characters. It treats
     * non-ASCII characters taking in account case differences. This is an 
     * attempt to mimic glib's string utility function 
     * <a href="http://developer.gnome.org/glib/2.28/glib-String-Utility-Functions.html#g-ascii-strcasecmp">g_ascii_strcasecmp ()</a>.
     *
     * This is a slightly modified version of java.lang.String.CASE_INSENSITIVE_ORDER.compare(String s1, String s2) method.
     * 
     * @param str1  string to compare with str2
     * @param str2  string to compare with str1
     * @return      0 if the strings match, a negative value if str1 < str2, or a positive value if str1 > str2
     */
    private static int compareToIgnoreCaseASCIIOnly(String str1, String str2) {
        int n1 = str1.length();
        int n2 = str2.length();
        int min = Math.min(n1, n2);
        for (int i = 0; i < min; i++) {
            char c1 = str1.charAt(i);
            char c2 = str2.charAt(i);
            if (c1 != c2) {
                if ((int) c1 > 127 || (int) c2 > 127) { //if non-ASCII char
                    return c1 - c2;
                } else {
                    c1 = Character.toUpperCase(c1);
                    c2 = Character.toUpperCase(c2);
                    if(c1 != c2) {
                        c1 = Character.toLowerCase(c1);
                        c2 = Character.toLowerCase(c2);
                        if(c1 != c2) {
                            return c1 - c2;
                        }
                    }
                }
            }
        }
        return n1 - n2;
    }
2 of 2
1

I wouldn't use Collator, having read its Javadoc, because you have no control over how the strings get compared. You can pick the locale, but how that locale tells Collator how to compare strings is out of your hands.

If you know that the characters in your strings are all ASCII characters, then I'd just use the String.compareTo() method, which sorts lexicographically based on unicode character value. If all the characters in the strings are ASCII characters, their unicode character value will be their ASCII value and so sorting lexicographically on their unicode value will be the same as sorting lexicographically on their ASCII value, which appears to be what g_ascii_stcasecmp does. And if you need case-insensitivity, you could use String.compareToIgnoreCase().


As I noted in the comment, I think you'll need to write your own comparison function. You'll need to loop through the characters in the string, skipping over the ones that aren't in the ASCII range. So something like this, which is a simple, stupid implementation and needs to be beefed up to cover the corner cases I imagine g_ascii_strcasecmp does:

public int compareStrings(String str) {
    List<Character> myAsciiChars = onlyAsciiChars(this.wordString);
    List<Character> theirAsciiChars = onlyAsciiChars(str);

    if (myAsciiChars.size() > theirAsciiChars.size()) {
        return 1;
    }
    else if (myAsciiChars.size() < theirAsciiChars.size()) {
        return -1;
    }

    for (int i=0; i < myAsciiChars.size(); i++) {
        if (myAsciiChars.get(i) > theirAsciiChars.get(i)) {
            return 1;
        }
        else if (myAsciiChars.get(i) < theirAsciiChars.get(i)) {
            return -1;
        }
    }

    return 0;
}

private final static char MAX_ASCII_VALUE = 127; // (Or 255 if using extended ASCII)

private List<Character> onlyAsciiChars(String s) {
    List<Character> asciiChars = new ArrayList<>();
    for (char c : s.toCharArray()) {
        if (c <= MAX_ASCII_VALUE) {
            asciiChars.add(c);
        }
    }
    return asciiChars;
}
🌐
Spring
docs.spring.io › spring-data › mongodb › docs › current › api › org › springframework › data › mongodb › core › aggregation › StringOperators.StrCaseCmp.html
StringOperators.StrCaseCmp (Spring Data MongoDB 5.0.0 API)
java.lang.Object · org.springframework.data.mongodb.core.aggregation.StringOperators.StrCaseCmp · All Implemented Interfaces: AggregationExpression, MongoExpression · Enclosing class: StringOperators · public static class StringOperators.StrCaseCmp extends Object ·
🌐
Java Tips
javatips.net › api › jpcsp-master › src › jpcsp › Allegrex › compiler › nativeCode › Strcasecmp.java
Strcasecmp.java example
If not, see <http://www.gnu.org/licenses/>. */ package jpcsp.Allegrex.compiler.nativeCode; import jpcsp.memory.IMemoryReader; import jpcsp.memory.MemoryReader; /** * @author gid15 * */ public class Strcasecmp extends AbstractNativeCodeSequence { static public void call() { int src1Addr = getGprA0(); int src2Addr = getGprA1(); IMemoryReader memoryReader1 = MemoryReader.getMemoryReader(src1Addr, 1); IMemoryReader memoryReader2 = MemoryReader.getMemoryReader(src2Addr, 1); if (memoryReader1 != null && memoryReader2 != null) { while (true) { int c1 = toLowerCase[memoryReader1.readNext()]; int c2 = toLowerCase[memoryReader2.readNext()]; if (c1 != c2) { setGprV0(c1 - c2); return; } else if (c1 == 0) { // c1 == 0 and c2 == 0 break; } } } setGprV0(0); } }
🌐
The Open Group
pubs.opengroup.org › onlinepubs › 009696799 › functions › strcasecmp.html
strcasecmp
Upon completion, strcasecmp() shall return an integer greater than, equal to, or less than 0, if the string pointed to by s1 is, ignoring case, greater than, equal to, or less than the string pointed to by s2, respectively.
Find elsewhere
🌐
Linux Man Pages
linux.die.net › man › 3 › strcasecmp
strcasecmp(3) - Linux man page
The strcasecmp() function compares the two strings s1 and s2, ignoring the case of the characters. It returns an integer less than, equal to, or greater ...
Top answer
1 of 4
9

strcasecmp() : A Non-Standard Function?

Short answer: As strcasecmp() is not in the C standard library, that make it non-C standard.

strcasecmp() is defined in popular standards such as 4.4BSD, POSIX.1-2001.

The definition of case-less functions opens the door to the nit-picky details. These often involve the positive or negative result of case-less compares, not just the 0 or non-0 as used by OP. In particular:

In the POSIX locale, strcasecmp() and strncasecmp() shall behave as if the strings had been converted to lowercase and then a byte comparison performed. The results are unspecified in other locales.

The trouble with this is with upper and lower case letters that do not have a 1 to 1 mapping. Consider a locale that has E, e and é but no É, yet toupper('é') -- > 'E' . Then with "as if the strings had been converted to lowercase", 'E' has 2 choices.

As a candidate portable solution consider one that round trips the letter (to upper then to lower) to cope with non 1-to-1 mappings:

int SGA_stricmp(const char *a, const char *b) {
  int ca, cb;
  do {
     ca = * (unsigned char *)a;
     cb = * (unsigned char *)b;
     ca = tolower(toupper(ca));
     cb = tolower(toupper(cb));
     a++;
     b++;
   } while (ca == cb && ca != '\0');
   return ca - cb;
}

Alternate code needed with select implementations with UCHAR_MAX > INT_MAX.

If you do not want to round-trip the values use:

     ca = tolower(ca);
     cb = tolower(cb);

Detail: toupper() and tolower() only defined for int in the range of unsigned char and EOF. * (unsigned char *)a used as *a may have negative values.

2 of 4
7

strcasecmp is not in the C or C++ standard. It's defined by POSIX.1-2001 and 4.4BSD.

If your system POSIX or BSD compliant, you'll have no problems. Otherwise, the function will be unavailable.

🌐
Quora
quora.com › What-is-the-difference-between-Strcmp-and-Strcmpi
What is the difference between Strcmp and Strcmpi? - Quora
Answer (1 of 2): Operationally, the strcmp function performs a case-sensitive comparison of null-terminated C strings, while strcmpi (where available) performs a case-insensitive comparison.
🌐
Qnx
qnx.com › developers › docs › 8.0 › com.qnx.doc.neutrino.lib_ref › topic › s › strcasecmp.html
strcasecmp()
#include <stdio.h> #include <strings.h> #include <stdlib.h> void compare( const char* s1, const char* s2 ) { int retval; retval = strcasecmp( s1, s2 ); if( retval > 0 ) { printf( "%s > %s\n", s1, s2 ); } else if( retval < 0 ) { printf( "%s < %s\n", s1, s2 ); } else { printf( "%s == %s\n", s1, s2 ); } } int main( void ) { char* str1 = "abcdefg"; char* str2 = "HIJ"; char* str3 = "Abc"; char* str4 = "aBCDEfg"; compare( str1, str2 ); compare( str1, str3 ); compare( str1, str4 ); compare( str1, str1 ); compare( str2, str2 ); compare( str2, str3 ); compare( str2, str4 ); compare( str2, str1 ); return EXIT_SUCCESS; }
🌐
GitHub
github.com › 32bitmicro › newlib-nano-1.0 › blob › master › newlib › libc › string › strcasecmp.c
newlib-nano-1.0/newlib/libc/string/strcasecmp.c at master · 32bitmicro/newlib-nano-1.0
strcasecmp · */ · #include <string.h> #include <ctype.h> · int · _DEFUN (strcasecmp, (s1, s2), _CONST char *s1 _AND ·
Author   32bitmicro
🌐
GitHub
github.com › lattera › glibc › blob › master › string › strcasecmp.c
glibc/string/strcasecmp.c at master · lattera/glibc
__strcasecmp (const char *s1, const char *s2 LOCALE_PARAM) { #if defined _LIBC && !defined USE_IN_EXTENDED_LOCALE_MODEL · locale_t loc = _NL_CURRENT_LOCALE; #endif · const unsigned char *p1 = (const unsigned char *) s1; const unsigned char *p2 = (const unsigned char *) s2; int result; ·
Author   lattera
🌐
Linux Man Pages
man7.org › linux › man-pages › man3 › strcasecmp.3.html
strcasecmp(3) - Linux manual page
The strcasecmp() function performs a byte-by-byte comparison of the strings s1 and s2, ignoring the case of the characters. It returns an integer less than, equal to, or greater than zero if s1 is found, respectively, to be less than, to match, or be greater than s2.
🌐
CS50
manual.cs50.io › 3 › strcasecmp
strcasecmp - CS50 Manual Pages
The strcasecmp() and strncasecmp() functions return an integer less than, equal to, or greater than zero if s1 is, after ignoring case, found to be less than, to match, or be greater than s2, respectively.
🌐
W3docs
w3docs.com › learn-php › strcasecmp.html
strcasecmp()
In this article, we will discuss the syntax and usage of strcasecmp(), as well as provide some examples.
🌐
Wikibooks
en.wikibooks.org › wiki › C_Programming › C_Reference › nonstandard › strcasecmp
C Programming/C Reference/nonstandard/strcasecmp - Wikibooks, open books for an open world
In programming language C, strcasecmp is a function declared in the strings.h header file (or sometimes in string.h) that compares two strings irrespective of the case of characters.