How can I make gzprintf (or printf in general) to use "." as decimal separator, effectively ignoring LC_NUMERIC or using "LC_NUMERIC = C".
Background: My program which uses gettext , does setlocale (LC_ALL, ....) to change it's locale. But at one point I need to write to a measurement file which should have a fixed "." as decimal separator. Of course I can do something like
const char *old = setlocale (LC_NUMERIC, NULL);
... make copy
setlocale (LC_NUMERIC, "C");
... use gzprintf
setlocale (LC_NUMERIC, old_copy);
but I fear runtime problems because I have to write samples with 2kHz to the file but haven't benchmarked it yet.
Not only is wrapping each call with setlocale like that potentially slow. It's completely thread-unsafe and thus unsafe to use in general/library code.
Assuming you're on a POSIX or POSIX-like system, what you want is newlocale/uselocale. Perform the following (which may be slow) once and save the result:
locale_t safe_locale = newlocale(LC_NUMERIC_MASK, "C", duplocale(LC_GLOBAL_LOCALE));
Then, whenever you want to use it:
locale_t old = uselocale(safe_locale);
/* Do stuff with it. */
uselocale(old);
You need not switch back and forth around each operation, only before returning to a caller that might expect its locale to be undisturbed, but it should not be slow to switch back and forth like this anyway.
Alternatively, just don't honor LC_NUMERIC in your application at all. After calling setlocale(LC_ALL, "") to setup the locale according to the user's settings, call setlocale(LC_NUMERIC, "C") and leave it that way. This is not valid/acceptable in library code, but if you're writing library code, you can punt and let the caller take responsibility for doing whichever approach it finds appropriate (never honoring LC_NUMERIC at all, or using newlocale/uselocale to switch). You can either just write this requirement in the documentation of its contract, and treat failure to honor the contract as undefined, or you can actively test for non-'.' radix point by asserting that localeconv()->decimal_point points to a string "." (and returning an error or aborting if that fails to hold).
Related
Am using the C JSON library under Ubuntu (json-c/json.h). I need to parse JSON strings on multiple POSIX threads. Am currently using the json_tokener_parse() method - is this multi-thread safe or do I need to use something else?
thnx
I looked through the code: https://github.com/json-c/json-c/blob/master/json_tokener.c
It appears to be thread-safe with one exception:
#ifdef HAVE_SETLOCALE
char *oldlocale=NULL, *tmplocale;
tmplocale = setlocale(LC_NUMERIC, NULL);
if (tmplocale) oldlocale = strdup(tmplocale);
setlocale(LC_NUMERIC, "C");
#endif
So if HAVE_SETLOCALE is defined (and it probably will be), setlocale() will be called and it will set the process-wide LC_NUMERIC to "C". And of course it undoes this at the end. This will cause problems if your LC_NUMERIC is not "C" or a compatible locale at the beginning, because one thread will "restore" your locale while another one may still be parsing and expecting the "C" locale to be in effect.
Fortunately it is guaranteed that the locale will be "C" on program start, so you just need to make sure that neither you nor any other library you're using sets LC_NUMERIC (or LC_ALL of course) to a locale incompatible with "C". You could then rebuild the library with HAVE_SETLOCALE undefined if you want, but this probably doesn't matter, as its calls to setlocale() will have no real effect.
I have an issue with fgetws and wprintf.
NULL is returned when a special character is fund in the File opened before. I don't have this problem with fgets.
I tried to use setlocale, as recommended here : fgetws fails to get the exact wide char string from FILE*
but it doesn't change nothing.
Moreover, wprintf(L"éé"); prints ?? (I also don't have this problem with printf) in the terminal (on Ubuntu 12), what can be done to avoid this?
Edit : as it is asked in the comments, here is the very simple code :
# include "sys.h"
#define MAX_LINE_LENGTH 1024
int main (void){
FILE *File = fopen("D.txt", "r");
wchar_t line[MAX_LINE_LENGTH];
while (fgetws(line, MAX_LINE_LENGTH, File))
wprintf(L"%S", line);
fclose(File);
return 0;
}
By default, when a program starts, it is running in the C locale, which is not guaranteed to support any characters except those needed for translating C programs. (It can contain more as an implementation detail, but you cannot rely on this.) In order to use wchar_t to store other characters and process them with the wide character conversion functions or wide stdio functions, you need to set a locale in which those characters are supported.
The locales available, and how they are named, vary by system, so you should not attempt to set a locale by name. Instead, pass "" to setlocale to request the "default" locale for the user or the system. On POSIX-like systems, this uses the LANG and LC_* environment variables to determine the preferred locale. As long as the characters you're trying to use exist in the user's locale, your wprintf should work.
The call to setlocale should look like:
setlocale(LC_CTYPE, "");
or:
setlocale(LC_ALL, "");
The former only applies the locale settings to character encoding/character type functions (things that process wchar_t). The latter also causes locale to be set for, and affect, a number of other things like message language, formatting of numbers and time, ...
One detail to note is that wide stdio functions bind the character encoding of the locale that's in use at the time the stream "becomes wide-oriented", i.e. on the first wide operation that's performed on it. So you need to call setlocale before using wprintf.
I'm writing some C code and use the Windows API. I was wondering if it was in any way good practice to cast the types that are obviously the same, but have a different name? For example, when passing a TCHAR * to strcmp(), which expects a const char *. Should I do, assuming I want to write strict and in every way correct C, strcmp((const char *)my_tchar_string, "foo")?
Don't. But also don't use strcmp() but rather _tcscmp() (or even the safe alternatives).
_tcs* denotes a whole set of C runtime (string) functions that will behave correctly depending on how TCHAR gets translated by the preprocessor.
Concerning safe alternatives, look up functions with a trailing _s and otherwise named as the classic string functions from the C runtime. There is another set of functions that returns HRESULT, but it is not as compatible with the C runtime.
No, casting that away is not safe because TCHAR is not always equal to char. Instead of casting, you should pick a function that works with a TCHAR. See http://msdn.microsoft.com/en-us/library/e0z9k731(v=vs.71).aspx
Casting is generally a bad idea. Casting when you don't need to is terrible practice.
Think what happens if you change the type of the variable you are casting? Suppose that at some future date you change my_tchar_string to be wchar_t* rather than char*. Your code will still compile but will behave incorrectly.
One of your primary goals when writing C code is to minimise the number of casts in your code.
My advice would be to just avoid TCHAR (and associated functions) completely. Their real intent was to allow a single code base to compile natively for either 16-bit or 32-bit versions of Windows -- but the 16-bit versions of Windows are long gone, and with them the real reason to write code like this.
If you want/need to support wide characters, do it. If you're fine with only narrow/multibyte characters, do that. At least IME, trying to sit on the fence and do some of both generally means you end up not doing either one well. It also means roughly doubling the amount of testing necessary without even coming close to doubling the functionality you provide to the user.
What is the safe/portable way to convert a number to a string (and the other way around) ?
I'm on Linux and my settings locale is so that when I use sprintf numbers have a "," instead of a "." as a separator.
Sometimes I want them that way, Sometimes not :)
I saw some solutions that imply playing with users settings. Clearly that's something one should not do. Somebody suggested using uselocale
snprintf : simple way to force . as radix?
can someone elaborate a bit (looks like it's buggy on some glibc (<2.12)) and if possible provide some sample code (eg a macro SNPRINTF_POSIX).
I tried myself but my C skills are very limited.
[edit]
I find this code by [GO]Skywalker13 on Swisslinux.org after writing my question.
Any thoughts about it ? What about memory usage ? (I need to make numerous calls to this func)
#define _GNU_SOURCE
#include <locale.h>
#include <stdlib.h>
double
my_atof (const char *nptr)
{
double res;
locale_t new_locale;
new_locale = newlocale (LC_NUMERIC_MASK, "C", NULL);
res = strtod_l (nptr, NULL, new_locale);
freelocale (new_locale);
return res;
}
With POSIX 2008, you can use the newlocale and uselocale functions to temporarily change the locale in the current thread without affecting other threads. This is really the only solution, aside from never setting the LC_NUMERIC locale category to begin with. On the other hand, I prefer banning use of LC_NUMERIC in software I write, at least for the global locale. Then you can use newlocale and uselocale locally at the point where you want numeric formatting that matches your user's cultural conventions, and on systems that lack POSIX 2008 uselocale, simply leave out localized numeric printing.
I recently came across a rather unusual coding convention wherein the call for a function returning "void" is prefixed with (void).
e.g.
(void) MyFunction();
Is it any different from the function call like:
MyFunction();
Has it got any advantage or is it yet another needless but there coding convention of some sort?
Some functions like printf() return a value that is almost never used in real code (in the case of printf, the number of characters printed). However, some tools, like lint, expect that if a function returns a value it must be used, and will complain unless you write something like:
int n = printf( "hello" );
using the void cast:
(void) printf( "hello" );
is a way of telling such tools you really don't want to use the return value, thus keeping them quiet. If you don't use such tools, you don't need to bother, and in any case most tools allow you to configure them to ignore return values from specific functions.
No, there isn't any difference -- what's being cast to void is the return value of the function.
I'd say it could make sense of you wanted to make explicit you're not using the return value (you're calling it for the side effects), but as the function already has void return, it doesn't make much sense.
If the function returns something the void could avoid (!) a warning (indeed in no way I was able to make gcc warn me that the return value is lost) on some compilers (or lint tools); but more importantly, it makes clear that a return value is "thrown" away purposely (and not by mistake).
acedemically: a "function" always returns something, else it would be a procedure. So the Author of this code wants to say "i know this naming is wrong, but i will no change the name, so i make this disturbance visible"
Has it got any advantage or is it yet another needless but there coding convention of some sort?
No difference. It is a quite common convention e.g. in software testing to highlight the fact that in context the function return, if any, is safe to be discarded.
In HPUX man pages it is quite common in example code to see a cast to void to get around lint warnings.
fprintf(mystream, "%s\n", "foo");
vs.
(void)fprintf(mystream, "%s\n", "foo");
That may be where the author of the code is coming from. IMO, this is not a great idea because most of the sprintf family, for example, call malloc. malloc will fail when there is not enough memory. SIGINT also causes the underlying write() syscall to interrupt and not write all of the buffer, for printf() family members.