01-14-2009 01:59 PM
After working with LabVIEW, I'm giving a try with LabWindows for writing a GPIB driver. LabVIEW provides a format modifier, something like %.;%f;%d to read in a float and an integer, where the decimal character is a "." regardless of the locale (e.g. German locale's use a comma instead of a period).
Looking at the functions in CVI 9.0, I don't seem to be able to determine how to generate strings that are independent of locale, that is, always use a period for a decimal separator instead of the local, and viceversa when interpreting a string, e.g. a function strtod().
There's the setlocale() function, but how does that go with multithreading when I need to print something with the current locale (e.g. with comma 12,10) but need to send something out over GPIB with a period instead (e.g. WAVE 12.10)
01-15-2009 03:52 AM
Well, depending on how complex your strings are likely to get, I can think of a couple of ways to do this. For strings to send to an instrument, you could just scan the locale-dependant generated string for a ',', and replace it with a '.'. This is a bit simplistic, especially if there is a possibility that your instrument strings might really want a ',' at some point.
A more robust way is to always generate two strings, one with locale set on and another one with it set off. In a multi-threaded environment, you would probably want to protect the section of code which turns locale off with a Critical Section, so that temporary changes would not interfere with the rest of the program.
JR
01-15-2009 05:10 PM
C programs are initialized with the "C" locale - this is a locale that is independent of your regional/language settings and always uses a period to represent the decimal point. If your programs are for some reason using some other locale, then you can set them to use the C locale by calling:
setlocale( LC_ALL, "C" );
If you want to use the OS's default locale, then call:
setlocale( LC_ALL, "" );
This will cause the ANSI C library to use the region specific decimal point representation.
setlocale affects the locale of all threads, so you should protect the code using a critical section, as JR mentions.
For example:
void PrintInLocale(const char *locale)
{
char *prevLocale;
CmtGetLock(myLock);
prevLocale = setlocale( LC_ALL, NULL ); // get current locale
if (setlocale( LC_ALL, locale ) == NULL) // change locale
printf( "ERROR: could not change locale!\n" );
else
{
printf(...); // do your formatting stuff
setlocale( LC_ALL, prevLocale ); // reset the locale
}
CmtReleaseLock(myLock);
}