views:

107

answers:

3

The program saves a settings file as text which contains floating point numbers of type long double. The settings file can only be saved via the GUI (GTK2), while files can also be loaded via the command line and without bringing up the GUI.

Unfortunately, a user reports that in the files he has saved, due to his locale setting, the numbers are formatted with commas and the program refuses to load them (emitting error messages) from the command line but seems to load them when the GUI is open.

I have already asked the following question: MPFR, printf, decimal places, locales, file i/o problem which suggested using setlocale(LC_ALL, "C") which I placed at the beginning of main. As this did not work, I placed it after calling gtk_init_check but again, it made no difference. (EDIT It did make a difference after I installed a few locales.)

I want the program to always use the same locale setting (or non-localized locale setting - "C") for these data files it saves, but don't want to mess up the GUI by doing so.

How?

A: 

If you can live with only storing these values as double, I would simply suggest using glib's ASCII-limited string formatting/parsing functions:

To convert a value to string, call g_ascii_dtostr(). To go the other way, use g_ascii_strtod().

I realize this might be bad since you drop precision going from long double to plain old (g)double, of course. It doesn't seem glib supports a long double type, are you sure it really gives you more precision?

unwind
Errrh absolutely sure... Actually some of the floats use the MPFR library for even more precision and the output of the MPFR functions also has the same problem.
James Morris
A: 

Store the locale in use at the top of your load/save code:

char* loc = setlocale(LC_NUMERIC, NULL);

Then for every instance where you write numeric values to your file call:

setlocale(LC_NUMERIC, "C");
/* code here for read/write of numeric values:
fprintf(fd, "aspect %0.20lf\n", img->aspect);
*/
setlocale(LC_NUMERIC, loc);

Should do the trick.

James Morris
I discussed this approach on the gtk-app-devel list. Initially I misunderstood vitaly.v.ch's answer and this is reflected in my first post there. After several posts I am left concluding that in my particular case the store/restore approach is ok.Thread starts: http://mail.gnome.org/archives/gtk-app-devel-list/2010-January/msg00127.htmland continues: http://mail.gnome.org/archives/gtk-app-devel-list/2010-February/msg00000.html
James Morris
+1  A: 

do not use locale sensitive functions for save and restore values at all. For example use ieee754.h for save and loading mantissa and exponent.

vitaly.v.ch
Could you explain briefly as to why I should not save/restore locale settings?
James Morris
That's not what he said.A locale-sensitive function for printing a number to a file will format that number according to the locale, with commas etc. A locale-insensitive function will always print the number the same way no matter what locale you are in. Always use locale-insensitive functions for internally written files that users will not hand-edit. (Such as settings files.)
ptomato
These are config files. They are meant to be machine readable and the machine really doesn't care for your national sensitivities. Making the config files commented, human-readable and human-editable is an appreciated though not essential bow towards usability and openness. Making config files localized, including localized formatting of actual config data is harmful and an abuse of "political correctness" (as you just experienced). GUI should be localized. Text config tool can be localized. Config files should not.
SF.
It's wrong. I talk about system header ieee754.h not about standard ieee754.h.
vitaly.v.ch
-1 ieee754 does not have the precision required.
James Morris
You need IEEE Std 754-2008. http://en.wikipedia.org/wiki/Quadruple_precision_floating-point_formatAnd last gcc/glibc for compiling.
vitaly.v.ch