How To Sort in C++

... So I was attempting to write an extremely obscure out-of-the-way function in C++: I wanted — send the children from the room! — to sort lines of text without case sensitivity! ... Since you will doubtless be unaware of the subtleties of this super-computer-science secret decoder ring idea, case-sorted strings are like this —

I
am
frend
your

— while strings sorted without regard to case are like

am
frend
I
your

... Tricky, eh? ... Gotta fly in programmers from the coast, right? ... But please note: our problem domain is C++. ... I don’t want to sort barbaric insect-level C strings, no no; any fool can do that with qsort! ... No, I want to sort an EZ-to-use C++ string list, aka “std::list<std::string>”....

... So I googled and googled for hours and hours, and was reminded of the deathless sentiment of a fellow I worked with at Satellite Transmission Systems so many golden years hence: “you ask for the time, and he tells you how to build a watch”. ... The most useful page I found claimed to explain a “naive” way to accomplish the goal — without actually showing a working example — but then cautioned that, regardless of the seeming incomprehensibility of the solution, it wouldn’t work with text containing a ,1 and then proceeded to outline several additional bad solutions + various complexities, and when I gave-up I think was moving on to Superstring theory — but no working example....

... And that was the best I found. ... Excluding the outstandingly scammy “experts exchange” where you can submit your credit card to find out what they don’t know. ... After hours of search I could not find a single demonstration of case-insenitive C++ string list sorting....

... So I will divulge this innermost hermetic secret I discovered with my own primitive text editor and a few compilers. ... I realize my example is a little lengthy, as it includes comments — an exotic little-used programming element — but after my hours of googling I thought it was worth a shot. ... Anyway, here is how I and now you can case-insensitive sort a string list in C++ (and here is a little zip of the code):2

/**************************************************
howtosort.cpp
Wed 2/28/2007 6:42 pm creation
Mon 4/16/2007 6:51 pm discovered strcasecmp!

Reveals the hidden secret of the ages,
the uttermost hermetic gnostic truth:
how to do case-insensitive string sort
in C--.

Please note this code compiled successfully under
obsolete Borland Builder C++ version 5, and the
utterly update-to-date Macintosh X 10.4 g++!

j.g. owen * * * * * * * * * * * * * * * * * * *
web:   http://owenlabs.org/
email: owenlabs@aol.com
* * * * * * * * * * * * * * * * * * * * * * * *

**************************************************/

#include <stdio.h>
#include <string>
#include <list>

using namespace std;

typedef list<string> JSTRINGLIST;

#if defined(__GNUC__) && (__GNUC__ >= 4)
  #define stricmp strcasecmp
#endif

int jstringicmp(const string &one, const string &two) {
  return stricmp(two.c_str(),one.c_str());
}

bool mysort(const string &a, const string &b) {
  return jstringicmp(a,b)>0;
}

bool myrevsort(const string &a, const string &b) {
  return jstringicmp(a,b)<=0;
}

int main(void) {

  JSTRINGLIST what;

  what.push_back("drive_crazed");
  what.push_back("hey");
  what.push_back("Hey");
  what.push_back("Babe");
  what.push_back("drive");
  what.push_back("Me");
  what.push_back("crazed");
  what.push_back("Drive_crazed");
  what.push_back("Drive");

  what.sort(mysort);

  JSTRINGLIST::iterator i;

  for (i=what.begin(); i!=what.end(); ++i) {
    printf("%s\n",i->c_str());
  }

  what.sort(myrevsort);
  printf("\nBackwards:\n\n");

  for (i=what.begin(); i!=what.end(); ++i) {
    printf("%s\n",i->c_str());
  }

  return 0;

}

... I must concede there are a number of things obviously wrong with the example, clearly violating the ISO Hermetic Drivel Standard:

  1. It isn’t drowned, positively smothered covered oily scunged, in mumbo-jumbo.
  2. I don’t even refer to my doctorate, my seven other web sites, the university where I teach, and the really huge corporate buds I pal-around with.
  3. It works and is obvious.

... An actual fact: one reason it took me so long to decode the totally-opaque mumbo-jumbo of the web experts was because I had a bug in jstringicmp where I forgot to exit a for loop (no longer with us2), causing puzzling and annoying errors when I wandered out of range — these difficulties were of course made so obvious by the helpful transparent C++ errors and source debugging (translation: I spent a lot of time in STL “.h” files which are, of course, blindingly clear and easy-to-understand)....

— the ever-delving programmer
Tuesday, April 17, 2007


1. Sorting solutions involving toupper() will never be happy with ; probably not either. ... That would probably be because of its relentlessly ASCII nature. ... The point is, would the guru’s case-insensitive sorting solution work flawlessly with Japanese? ... And who cares? ... Obviously the Japanese would, but they’re clever people and will doubtlessly figure these things out; as will the Germans. ... I just don’t understand why I have to....

2. A version of this with my own slow-and-stupid version of stricmp was here for some months because g++ on my iMini (X 10.4) didn’t have one! ... Then the world turned and whaddya know!? ... They didn’t off stricmp; they just renamed it, to the incredibly intuitive “strcasecmp”! ... That is just so useful: the old cryptic STRing Ignore CoMPare exchanged for the obviously wrong STRing ignore(?!) CASE CoMPare! ... I suppose I should credit my source for this revelation: objective C propaganda from Apple (The Objective-C Programming Language, “ObjC.pdf”) used the so-appropriately-named strcasecmp in an example, and from my eyes the scales fell!


The Sins of C++ (and C)

The programming magazines are disappearing — and the jobs — and the remaining suspects concentrate on amazing new interpreted script thingeys. ... Why is that?! ... Oh Why!?!?...

Well ... J’accuse! ... It’s because the whole C++ megilla didn’t work! ... ! — the derivation, the polymorphism, the wretched templates — it was all a colossal waste of time! ... Oh, Owen, calm down, watch the blood pressure! ... Well OK of course there were doubtless many other factors in the collapse of my little professional interest-area, including the dot-com catastrophe and ever-menacing outsourcing. ... But still — so much language innovation — so little to show for it! ... Random example: the two best articles in a recent issue of the poor devolving Dr. Dobb’s were (1.) an autumnal shot from Petzold on the latest “XAML” nonsense in Vista (XMLish graphics scripty elements that sometimes auto-position themselves just like Java used to), and (2.) Programming the Cell Processor, with code entirely in C! ... Hardly an inheritor nor polymorph in sight!...

... Consequently, hereon out I resolve to turn kinder thoughts on those pertinacious promoters who were after all, professors of my profession, toilers in my vineyard. ... It didn’t work out, whatever their sins, and even ’though they lied and lied as hard as they could! ... Now the dust and smoke has cleared and so little remains! ... Below I summarize, for perhaps the final go-round, a hit parade of some C/C++ sins, and then turn away, so much more in sorrow than in anger ... and move on....

The $Billion Bug: #if UNDEF

In real software there are often “conditionals” which are used, for instance, to make it so one giant chunk of code can be compiled for two or more different versions of Unix. The C language supports this with “conditional expressions” including “#ifdef” and “#if”. I’ve always assumed #ifdef came first (because some primitive compilers include it, but omit #if), but in the 1978 K&R book The C Programming Language they’re both described on the same page (208). They’re used like

#ifdef NUCLEAR_THREAT
  printf("flee! death!");
#endif

#if NUCLEAR_THREAT
  printf("death! disaster!");
#endif

But what if the programmer’s an idiot like me, and typos

    #if NUCLER_THREAT
      printf("flee! death!");
    #endif

(i.e., typos “NUCLER” for “NUCLEAR”?) what happens? ... What happens is — at least in generations of C compilers I have known and reviled — even ’though the typo “NUCLER_THREAT” symbol-name is not defined anywhere in the program, it nevertheless quietly compiles, conditionalizing-out the “flee! death” warning, and a small third-world country like Cincinnati is incinerated....

... For contrast, there are analogous thingeys in assembler (aka “The Language of The Gods”) which work; in assembler

    if NUCLER_THREAT
      ldx #threat_message
      jsr print_string
    endif

would in fact emit a nasty error message during assembly when NUCLER_THREAT wasn’t defined, and refuse to assemble the program — which is exactly what should happen — and doesn’t — in C-language! ... For some reason the ancient gurus of C-language felt that the #if should act just like the #ifdef if the thing in question wasn’t defined. ... I don’t know why they felt this way; I suppose you had to be there. ... I once queried Plauger the Great, and he was uninterested. ... And of course most software won’t incinerate Cincinnati! ... No, it’ll just quietly erase your Excel spreadsheet or lock your Mercedes. ... The only way I can see this not being true is if all the programmers are smarter than me and never use #if — but aside from being smarter, they’d also have to be a lot less lazy, and that I won’t believe....

The Linux Solution: GNU gcc “-Wundef”

Recent up-to-date compilers — the kind I never use — at least have a warning: i.e., the GNU/Linux compiler option

    -wUndef Warn if an unidentified identifier is evaluated in an #if directive

which would also, I imagine, explain how it is that the kernel bunch has, it is said, banned #ifdef in favor of #ifs. ... Frankly, I am unable to discover if a recent Microsoft compiler has such a warning, at least in the brief time allocated to me on this earth. ... Wait whoa my VS 2005 includes the Microsoft compiler. ... Sadly, the “Warnings and Errors” page in the MSDN help is blank. ... If it’s in there, I couldn’t find it in 10 minutes. I did verify it’ll compile “#if UNDEF” with no complaint. ...

Delphi too

Oh my poor proprietary Borland Delphi! Recent versions have an “if” syntax which does the same thing:

{$if UNDEFINED}
#error:
{$endif}

It produces no error. ... I’m so disappointed....

C++ References: Misfeature?

There are (at least) two ways to pass arguments to program subroutines in a computer language: by value, and by reference. ... There might be code like

    int x;
    ...
    A_function(x); //by value; can’t change x.
    B_function(x); //by reference; can change x.
    ...

where “A_function” does something to x, but nevertheless leaves the original x unchanged, while B_function might, if it felt like it, add 17 to x, and the change would persist even after B_function departed. ... In such a case, it is said that B_function’s argument is treated as a reference, while “A_function” is passed x by value: a copy of x is supplied to “A_function”, and whatever it does with it won’t affect the original x....

... Now obviously a situation like that depicted above is bad, because when we’re reading the code, we can’t tell that one of the functions uses a reference, the other, a value. ... But, as a feature, C++ lets you do that. ... The standard K&R C, from whose forehead C++ sprang, doesn’t....

Bug/feature? It was commonplace for ignorant C++ propaganda to pretend that K&R C was too stupid to support references. ... But to those of us who know anything it’s obvious K&R was deliberately contrived that way, among other things, to avoid the ambiguity of “invisible” reference/value distinctions. ... So, in standard C, the above would be required to look like

    int x;
    ...
    A_function(x);
    B_function(&x); //ampersand means the value
                    //can be changed by the function.
    ...

... It’s unimportant what the “&” does; what’s important is it forces a distinction between the two kinds of argument-passing, thus making standard C inherently less buggy than C++ in this particular area; and it’s not because Dennis Ritchie was too dumb to know any better, but indeed was itself an ingenious and useful innovation over cruder languages. ... I believe the intricate object gimmickry of C++ requires the value/reference ambiguity....

The Standard Template Library aka STL1: Perfect Reusable Code

It’s a fundamental truth about the historical software concept known as reusable code (also, sometimes, as the “Holy Grail”): sadly, as opposed to relentless propaganda, reusable code like everything else in this vale of tears has costs along with its benefits. ... Numerous modern software lunacies have foolishly denied the cost part in their puffery: C-language libraries of yore, the “components” of Delphi and other languages — the latest Vista tripe follows the dishonorable tradition. ... I could pick at the STL’s particular annoyances, its incomprehensible error messages from the dark side, the ease and pleasure of debugging in it — but the truth is, it’s no different from the parade of language features down the wandering years: the good parts aren’t free! ... Judging by the reality today, something in C++ — and I’ll nominate templates and the STL, simply because they’re an order of complexity weirder than the rest of the language — was judged too costly by the language-consuming public....

STL Debugging

For the smartest people on earth, the C-- masters seem oddly indifferent to practical realities. Which are that debugging STL code is broken. It hasn’t worked. Ever....

The STL is a macroey thing embodied in include files. When I debug normal decent unincremented C and find myself constantly wandering into libraries I don’t really want to be in, it’s usually feasible to deaccess the source code to those libraries and voila, the debugger won’t go there. Sometimes. Often. ... It’s like this because this source is compiled to object code long ago, and runs in binary/object code libraries, and the source, if present, is just available as a treat, often a feature of the insane millionaire version. Lesser versions of commercial compilers often come without such source, expressly to annoy innocent beginners who want to know why they can’t step into the precious beautiful proprietary libraries of their chosen vessel.

There Is No STL Source

I can’t do that with the macroey STL source. It’s never separately-compiled and exists in no object or binary form. It’s better than that. It’s wonderful completely-without-cost macroey fairy dust source! ... If I exclude that, not only will I not be bothered by debugging into it, I will exclude the precious STL and the beloved string class entirely, and not be bothered by running it!

The practical effect of this is whenever I debug something that uses a C-- string, or a list, or any wonderful C-- thing, when I “step into” any function that uses any of those things — I don’t: I actually step into a totally alien forest of endlessly-meaningless macro gobbledygook that even Bjarne Stroustrup couldn’t comprehend on drugs. The only way to get to the next spot in my program is to laboriously set a breakpoint at the desired spot, introducing immense inefficiency....

For years I thought this was a deficiency of my humble ancient Borland Builder version 5, but I was recently astounded to realize that, in the fabled vales and gardens of C-- this is normal! ... In the great and awful Microsoft Visual Studio there’s some way to make it work correctly with handy obscure only-on-advanced-google-search registry hacks, but for FOSS and Borland ... well, you really like it that way, don’t you? I mean, why wouldn’t you want to step into a schizophrenic jungle of meaningless gobbledygook? ... Here I parrot the typical — although noticeably diminishing — C-- fan boy.

And that, children, is why the World of Windows now has so many thriving scripty Pythons and Rubys, which offer strings and lists without lethal weapons-grade debugging. Just the way the absence of a usable friendly programming environment — Turbo Pascal — made Linux such a Perl and even execrable Bash playground in those dark days. ... Well actually, unlike Turbo Pascal, the script languages typically offer no debugging, or at least very rudimentary version 0.0.0.2 forms, although supposedly their cuddly no-crash testability makes that so unimportant; or maybe it’s just general devolution....

The C-- gurus generally prefer a debugging-challenged language; keeps those nasty kiddies from inventing things and giving competitive seminars. One obvious effect on C-- was it became an adept/follower affair, with the brilliant gurus creating the STL, and the crude user proletariat — like me — consuming their beautiful creations. ... I personally wouldn’t dare alter anything in the STL, through inheritance or even staring at it too rudely, because I know my place and what’s good for me. ... Sadly this strategy failed the guru adepts, and their numbers for some reason diminish, perhaps because of the impossibility of debugging, much-less extending, their sacred cult-like objects, or perhaps it’s the absence of their native puffery suck-up computer magazines to advertise their ridiculous self-serving gobbledygook promotional articles....

& C++ is Ugly

Observe this pretty-much random example:

    copy(diffs.begin(),diffs.end(),
    ostream_iterator<int,char,char_traits<char> >(cout," "));

... And this is an example! ... Please; it is not good that a computer language looks like line noise2 — despite the gushing opinions of the guru-ocracy....

C++ is Stupid

At Sat 12/6/14 I happened-upon the perennial C-- question, “How to convert an integer to a string”. The Stackoverflow discussion, dated 2/14, is at least 470 lines long. ... It’s so EZ when it doesn’t work.

... But Still Useful

I do not wish to leave the impression that C/C++ is an evil pointless thing; it is still my favorite programming language, at least, and it is still widely used — the Linux kernel, probably the most prominent software project of our times, is C-language and likely to remain so. ... But not C++. ... I suspect the majority of C/C++ is still really C, no matter the “.cpp” extension; I know I often use C++ as a “super-syntax” checker to tidy-up my C code, and probably others do too. ... But I have nothing against the enhancements that C++ offers, and I’ll whip-up a class or use a built-in (kind-of) like the string type when it’s convenient....

... But what I wish, and what I’m fairly certain is not going to happen, is that C++ features were actually as easy-to-use as, say, the 1995 Delphi Pascal! ... Sadly, C++ features aren’t easy-to-use and indeed are significantly more annoying than newer and older languages — that’s the disappointment and, what with the passing of time and all, seems likely to remain so....

The Guru Plague

I used to whine endlessly on this site about the scurrilous gurus who flogged their ridiculous super software magical nostrums, mostly of the C++ persuasion; and actually I see I whine about it above a bit. ... But then the gurus disappeared, along with the computer magazines, their basic puffery support platform. ... But I realized recently the excesses of C++ and particularly the STL and its ilk were probably guru plague symptoms: they wouldn’t’ve happened without the gurus’ constant need for more cult material. In their hidden collegetown ghetto yurts, the bearded aging gurus will claim the computer culture failed and didn’t support their brilliant innovation, so we all lost. ... And I will stand up and cheer, yes....

They’re Back...

... Wait just a moment there fella! ... Apparently I cheered too soon — there remains a single software magazine I know of, Code, and in their 3/16 issue @ p 36, I started reading this strange unintelligible gobbledygook — well it was more so than the usual Code obfuscation: “DevOps and Continuous Delivery: Made for a Cloud World” seemed to be about nothing or who knows, and then I realized: this unintelligibility, the gnostic pretensions — it was the guru plague, not dead yet! ... As long as there’s a printed page to babble on. ... So I googled; the wikipedia article is predictably opaque, although far better than the article, at least getting to the point of admitting it was spawned at a 2008 “Agile” conference. Or maybe they didn’t mean that; they didn’t actually say it. ... Anyway the prize is a free IBM “Ebook” DevOps for Dummies which I would happily enshrine next to my DNS for Dummies if it were an actual book. ... The book tacitly concedes it’s a cult: The sections in the “What is DevOps?” first chapter are “Understanding the Business Need for DevOps”, “Recognizing the Business Value of DevOps”, and “Seeing How DevOps Works” — but not “How DevOps Works”. The guru won’t tell us; of course. You must pay for the seminar/conference. ... It writes “the DevOps movement has produced several principles”, and conceivably it could product more, given enough conferences, seminars, corporate ca$h. ... Ahhh, it’s heady stuff, the whiff of the gurus, their harmless conferences, their pitiful thirst for money and tribute.....

— the once-but-not-future-professional programmer
Wednesday 5/31/17 9:46 am


1. If you have a copy of Borland’s C++Builder version 5, there is a charming antique directory of STL examples somewhere around c:\Program Files\Borland\CBuilder5\Examples\StdLib\; they never finished the GUI demo program there, but I did — more-or-less — and here it is; you have to replace their std1.* with the three source files in jgostl.zip; see comments in my std1.cpp....

2. Knowing what “line noise” means shows I’ve been failing to measure-up since RS232 terminals were popular, upon which the gay crashing electrons would produce amusing trails of meaningless punctuation and odd characters — i.e., just like powerful modern programming languages....


C++ INI Files!

Just to show I’m a really smart fellow and there’re no hard feelings about those C-- sins ’n’ all, here is the beautiful and talented JDB.ZIP including the complete C++ source for a Windows-style INI file implementation. ... Which, when I was looking for one, I couldn’t find for love or money — well, maybe for money, although who can tell? ... Anyway, over the years I’ve found Windows-style INI files an easy and predictable way to provide options for my software, so I wrote my own C++ version; and when I use it every year or so it often works and I don’t find more than 2 or three dangerous bugs, although of course your home and pets will disappear in a flaming ball of burning gas. ... + you get the “jdb” utility which as well as demonstrating my jIni class implements a little database feature using an INI file.

Wonders to Behold!

Finally — you may want to sit down for this — I am so smart that JDB compiled, at least once, with Borland’s pitiful C++Builder, and a ming GNU compiler I got hold of for Windows, and — ta-da! — the g++ that came with the Macintosh OS X in my imini! ... All with a single source! ... Totally portable! ... Today only!

And now — compiled in Microsoft Visual Studio 2005! ... Will the wonders never cease?!

— the humble programmer
Friday, March 8, 2013 1:55 pm


The Sorcerer’s Apprentice: Help

Recently, after Microsoft stold it from me for a while, I realized the central position “Help” has in the broken stained-glass imbroglio of my illustrious career. ... For you youngsters, “Help” was something Microsoft tried to force developers to include in their software, where the user’d be able to press the F1 key and gloriously-informative tripe would spring into a special help window, to beat back ignorance, confusion, and fear.

But then the Macintosh was so EZ it didn’t need no stinkin’ help. And they must’ve been right, ’cause in a few wandering years Microsoft followed their usual path of (1.) first crippling the feature with ridiculous complicated “enhanced” versions and (2.) then abandoning it without any support. ... Well, hardly any: Microsoft might still let you get hold of the old version if you’re very very nice; and if they’re not in a bad mood....

Help for the Helpless

But what of the developers? Who will help us? ... Well, kiddies, therein lies my tale. When we used to write our pitiful assembly language scrivenings in the dark ages, there was no help! ... I have a little Motorola book that tells me all I need to know about my beloved 68HC11 or at least it better, ’cause that was all there was. ... Fortunately, there wasn’t much one could do with the naked 8-bit microprocessor of yore, but it certainly added to my wizardly credentials to have some vague grasp of the essentials which, however, could only be properly deployed with the aid of the printed book of spells, which I’d assiduously hoard and hide from poaching colleagues....

At the beginnings of the days of the exalted high level C language, it was much the same: it was in some ways simpler. But there were commercial crib sheets, beautiful plastic 8x10’’ cards with a summary of everything you needed to know to program in C. And it was good. ... But then it got complicated, and we’d have to consult giant books to find the right function amongst the swarming multitudes, and it was hard.

But then Ander Hejlsberg rode in with Turbo Pascal, a saintly IDE which, of course, included highly-developed help: context-sensitive! I’d just move the cursor to something and press @H and voila! Copious description of the function would burst onto the very screen I was writing the program with! Of course we still had to know the name of the spell, and for that the big books were still requisite — and now, the world wide web — but the details of how the spell worked? — it was right there at my fingertips.

Without Spells, Magic Dies: the Dark Usux™

What is the burden of my sad story? ... Well, basically, that when Microsoft stold the help files from my antique Delphi and Builder IDEs, it was as if the magic around me collapsed; I could see the little sparkly clouds falling to the floor; my well-worn spells were dust. I couldn’t write software and was sorrowful, hackless. I mean who the heck knows the arguments to findfirst()?!?!? ... Even ’though the only software I write is for myself in my little imaginary kingdom, in paradise....

Today’s kids, of course, use modern software. The great FOSS legions have various dubious IDEs with dubious help abilities, but the real men who pound the rivets of Linux don’t need no stinkin’ IDE, nor help. They are born whole with all the magic in their giant science-fictiony brains. We mortals need not apply, and I won’t. ... Indeed, aside from the anti-functionality of copy extortion, I reject the gates of the Giant Stupid Modern IDE at least partly because the help has doubtless devolved, like all things in this weary wandering world of woe.

So I will go my own way, patching and propping-up my antique software environments, and their antideluvian help. ... Wish me luck, passing programmer, and spare a thought, if not a tear, as you hack away in your super jscript, with everything you need in your giant brain....