The Sound of CAny old-timer in the audience who remembers Confetti's? :-)Format specifiers (such as
%s,
%d,...) are a dangerous species: They seem friendly but they actually wait for translation-time to bite. And they bite you in the most horrible way: You don't realize it until it's way too late. Your leg is infected and the only possible cure is to cut!
Let me explain what I mean. Please wear translator glasses for a second: Now you can translate in different languages. Great! But wait, what do they mean with this
%s is %d years old ? There's garbage in that program...
You get it: Translators are not programmers and anyone who is not a programmer doesn't have a damn clue about format specifiers. Chances are they will trash the specifiers in your format strings. And when I say you don't realize it unitl it's too late, I mean you won't find trashed specifiers: They are a needle in a haystack. The one who will find it is the user hitting the associated piece of code: Crash!
appTranslator 2.0 to the RescuePfeeew... We're safe! appTranslator 2.0 is coming soon to a download site near you.
Every time the translator clicks OK in the translation box, appTranslator now looks for format specifiers in the source and translation. If they don't match, a diagnostic warning is displayed, helping the translators catch errors early.

The cherry on the cake is the Help button that leads to an help page that teaches translators what a format specifier is how they should care about them. Just in case you forget to tell them, now they know.
OK, but how can you, the developer or localization engineer, be sure that translators didn't abusively reply Yes to the question above? appTranslator 2.0 features a new Translations/Analysis menu that performs various checks (such as format specifiers consistence) on the whole project contents. The results are displayed in the new Output Window. Easy navigation to the erroneous items is provided using F4 and Shift+F4 keys. That way, you can very easily double-check possible errors and make sure they won't bite you when yourprogram is out in the wild.

[Enlarge]
You do use FormatMessage() (or CFMsg), don't you!
Ouch! I can't believe I never talked about this in my blog :-(
OK, here's the short story: Never use
printf-like functions to display texts that require translation. Because the order of formatted fields in the translation may be different, due to differences in language constructions. And your code won't know. I let you think of what will happen when
%d blah %s is used where your program expects
%s blah %d !
The Windows API
FormatMessage() comes to the rescue: It works on the same principle as printf but adds formatted fields indexing, hence allowing fields re-ordering:
%2!d! blah %1 works as fine as
%1 blah %2!d!. More explanations + helper code in the appTranslator docs and in
a Code Project article of mine.
Of course, appTranslator supports FormatMessage-like format specifiers as well.
Relax: thanks to appTranslator 2.0, your program won't crash because of uncaught translation errors.