C – Can I Define custom true/false values?

Hello I want to define some custom statements. For example in Polish language we have letters 'a' than 'ą' and than 'b' and I want to do something like this

#define a > b && ą > b

I need this to comprasion in if statement to sort words so this should work like

if(ą > a) //false from define 

2 answers

  • answered 2021-04-21 16:35 Emanuel P

    No, you can't do that. You would have to do that with either a (inline) function, or a function like macro. And if it is for sorting, you should keep in mind that that would sort based on integral representation of the character, which is not necessarily alphabetical.

  • answered 2021-04-21 18:05 Kuba hasn't forgotten Monica

    You have an instinct for a programming language where you could define some facts and use them later, in a straightforward way. This is a way more abstract level of expression than what you can write directly in C. The programming language you're looking for is Mathematica, most likely. You could use its symbolic rule substitution to establish rules that order the abstract set element ą after a, and then use these rules to obtain statements about relative order of a variety of elements, even in more complex expressions (you could define character concatenation, etc. - all abstractly and how a mathematician would think of it, rather than what C lets you express directly). Or you could just use Mathematica's vast library of facts, e.g. Alphabet["Polish"] returns the Polish lowercase alphabet as a list: {"a", "ą", "b", "c", "ć", …, "ż" } - this could be used to establish a sort order.

    If you want to do this in C, then:

    1. The characters already have proper collation sequence in Polish locale. If your system is set to Polish locale, this will be happening already.

    2. To compare the characters, you cannot use the plain C comparison operators, since those compare the numerical values of the characters, whereas those numerical values have not much to do with collating order. Use C's strcoll function to compare strings (which can be single-character strings if you wish!).

    You could of course write a semi-baked strcoll yourself, and a simple way of doing it may be as follows:

    #include <assert.h>
    #include <wchar.h>
    
    int wcharpos_pl(wchar_t ch) {
      static const wchar_t alphabet[] = 
        L"\0AĄBCĆDEĘFGHIJKLŁMNŃOÓPQRSŚTUVWXYZŹŻaąbcćdeęfghijklłmnńoópqrsśtuvwxyzźż";
      enum { alphabet_size = sizeof(alphabet) / sizeof(alphabet[0]) };
      for (int i = 0; i < alphabet_size; ++i)
        if (alphabet[i] == ch) return i;
      return alphabet_size + (int)ch; // fall back to numerical order outside of the alphabet
    }
    
    int wstrcoll_pl(const wchar_t *left, const wchar_t *right) {
      while (*left == *right && *left) { // step through strings as long as they are equal
        ++left;
        ++right;
      }
      const int l = wcharpos_pl(*left), r = wcharpos_pl(*right);
      if (l < r) return -1;
      if (l > r) return 1;
      return 0;
    }
    
    int main() {
        assert(wstrcoll_pl(L"koktajl", L"koktajl") == 0);
        assert(wstrcoll_pl(L"Abrakadabra", L"abrakadabra") < 0);
        assert(wstrcoll_pl(L"matwa", L"mątwa") < 0);
        assert(wstrcoll_pl(L"żurawina", L"źrebak") > 0);
        assert(wstrcoll_pl(L"Żur", L"Żurawina") < 0);
        assert(wstrcoll_pl(L"ŻURAWINA", L"ŹREBAK") > 0);
        assert(wstrcoll_pl(L"źdźbło", L"ździebko") > 0);
    }