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.home.att.net/ email: owen_bda4@yahoo.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:
... 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 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++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 it didn’t work! ... The whole C++ megilla! — 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 elements that sometimes auto-position themselves just like Java!), 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....
|
#ifdef
NUCLEAR_THREAT | #if
NUCLEAR_THREAT |
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....
Recent up-to-date compilers — the kind I never use — at least have a warning: i.e., the GNU/Linux compiler option
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. ...
Oh my poor proprietary Borland Delphi! Recent versions have an “if” syntax which does the same thing:
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. ...
The
STL1
Templates: Perfect
Reusable CodeIt’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....
Finally, observe this pretty-much random example:
... 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....
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! ... That 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 sometimes-professional programmer
Wednesday, March 21,
2007 10:26
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; noise would produce amusing trails of meaningless punctuation and odd characters — i.e., just like powerful modern programming languages....

|
Another kind of C: Apple’s Xcode IDE
... As shown in the compelling illustration, if you use Apple’s Xcode IDE with the “Cocoa” framework — i.e. the Apple-recommended way to write new software for the Mac — you just draw connections from the cute Macintosh GUI forms and buttons and controls to your software! ... To heck with that boring code writing! You just click this and that, draw some lines, click a “Connect” button and Voila! ... It’s all done! ... Indeed, practically all the Objective C Code for my very first Macintosh program is #import "HelloController.h"@implementation HelloController - (IBAction)sayTheThang:(id)sender { [helloSayer setStringValue:@"Apres dumb"]; [text2_outlet setStringValue:@"2 dumb"]; } @end
IBOutlet
NSTextField *helloSayer; + that cute little graphical thingey up there, when I selected it in the “connections” gadget. Presumably the wild ’n’ crazy Objective C run-time fills them in, perhaps from the instructions in the “NIB” file that the EZ graphical stuff created, and points them to actual graphical text fields somewhere in space somehow.... Forbidden Knowledge... But what, I plea, panting and sweating, what if I want to know where they really are, what their real names are, huh huh? ... “Why would you want to know that?” the all-knowing guru snarls with a sneer; “that is not for you, mere programmer!” as, in a swirling black cape, she leaves the programming dungeon, perhaps flicking a cattle-prod at a private part on the way.... ... Anyway, there are numerous one-way GUI tools available for various platforms, which you can use to create your interface when you start writing a program; but then subsequently they’re not very useful as you elaborate the code and, presumably, how it looks. ... That is, if you never change the user interface, these one-way things work great! ... And the Apple gadget is one of them — even ’though the Xcode propaganda uniformly observes omerta on the subject — and I know this because I deleted the second text field in the GUI editor, compiled and ran, and nothing complained! ... Worked great! ... Even ’though the code was now referencing a presumably “nil” pointer (which, apparently, is a strength of Objective C, it’s so clever1) — or perhaps my code writes to an invisible text box which now will never die!?! ... (For more on GUI programming automation, see my newly-coined GUIRAD term.)
|