By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
457,948 Members | 1,484 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 457,948 IT Pros & Developers. It's quick & easy.

Can not `setlocale(3)' more than once in Linux

P: n/a
Hi,

I am in Linux writing a program using setlocale(3). But I found, only
the first invocation of setlocale(3) can be success, any subsequent
calling of this function will fail ( return NULL ) and the locale is
not changed. Is there any tip here?

Thanks.
#define _(String) gettext (String)

static void init_lc( const char* lc )
{
setlocale( LC_ALL, "" );
bindtextdomain( "hello", "/usr/local/share/locale" );
textdomain( "hello" );
}

int main( void )
{
init_lc( "" );

printf( _("Current locale is %s\n"), setlocale( LC_ALL, NULL ) );
printf( _("press 'e' to select English, 'c' to select Simplified
Chinese: ") );

int c;
while ( true ) {
c = getch();
if ( c == 'e' )
setlocale( "en_US" );
else if ( c == 'c' )
setlocale( "zh_CN" );
printf( _("press 'e' to select English, 'c' to select
Simplified Chinese: ") );
printf( _("Hello, world!\n") );
}

return 0;
}
Jun 27 '08 #1
Share this Question
Share on Google+
7 Replies


P: n/a
Steven Woody <na********@gmail.comwrites:
I am in Linux writing a program using setlocale(3). But I found, only
the first invocation of setlocale(3) can be success, any subsequent
calling of this function will fail return NULL ) and the locale is
not changed. Is there any tip here?
All I can say is that is not the case on my system. I can call
setlocale as often as I like. The program you posted should not have
compiled and certainly would not have been able to set the locale
since all but on of the calls was badly formed so it is not clear to me
how you even know there is a problem.

Although the function is standard, the standard says very little about
what locale strings mean, so you will need to post in, say,
comp.unix.programmer to get more help. Before you do, prepare a small
example that illustrates the problem you are having. The solution may
be simple.

--
Ben.
Jun 27 '08 #2

P: n/a
On 25 Apr 2008 at 7:37, Steven Woody wrote:
I am in Linux writing a program using setlocale(3). But I found, only
the first invocation of setlocale(3) can be success, any subsequent
calling of this function will fail ( return NULL ) and the locale is
not changed. Is there any tip here?
[snip]
if ( c == 'e' )
setlocale( "en_US" );
else if ( c == 'c' )
setlocale( "zh_CN" );
The prototype for setlocale is
char *setlocale(int category, const char *locale);

You're missing an argument.

Jun 27 '08 #3

P: n/a
On Apr 25, 11:55 pm, Antoninus Twink <nos...@nospam.invalidwrote:
On 25 Apr 2008 at 7:37, Steven Woody wrote:
I am in Linux writing a program usingsetlocale(3). But I found, only
the first invocation ofsetlocale(3) can be success, any subsequent
calling of this function will fail ( return NULL ) and the locale is
not changed. Is there any tip here?
[snip]
if ( c == 'e' )
setlocale( "en_US" );
else if ( c == 'c' )
setlocale( "zh_CN" );

The prototype forsetlocaleis
char *setlocale(int category, const char *locale);

You're missing an argument.
Sorry, when I modified the original code to make it simple to show
you, I made some errors. But the original code is right and I did
supplied correct arguments. Well, below is a correct version of the
code and I made it more simple to illustrate the problem:

#include <libintl.h>
#include <locale.h>
#include <stdio.h>

int main( void )
{
printf( "Current locale is %s\n", setlocale( LC_ALL, NULL ) );

bindtextdomain( "hellonls", "/usr/local/share/locale" );
textdomain( "hellonls" );

const char* msg = gettext( "Hello, world!" );

if ( ! setlocale( LC_ALL, "en_US" ) )
fprintf( stderr, "setlocale( en_US ) error\n" );
printf( "%s\n", msg );

if ( ! setlocale( LC_ALL, "zh_CN" ) )
fprintf( stderr, "setlocale( zh_CN ) error\n" );
printf( "%s\n", msg );

if ( ! setlocale( LC_ALL, "" ) )
fprintf( stderr, "setlocale( \"\" ) error\n" );
printf( "%s\n", msg );

return 0;
}

I found only the 3rd invocation of setlocale( ... ) can be success,
that is, I can only set locale to the system default. The calling
lines with "en_US" and "zh_CN" failed and returned NULL. So if my
system has LC_ALL=en_US, the code will print three same lines of
"Hello, world!" in english on the stdout, and If I set the LC_ALL to
zh_CN before run the code, I will got three same lines of "Hello,
world!" in Chinese.

Could you please try the code and tell me what's wrong here? You may
need to change "zh_CN" to a suitable locale to you. Thanks.

-
woody
Jun 27 '08 #4

P: n/a
On 27 Apr 2008 at 15:42, Steven Woody wrote:
I found only the 3rd invocation of setlocale( ... ) can be success,
that is, I can only set locale to the system default. The calling
lines with "en_US" and "zh_CN" failed and returned NULL.
The first thing you could try is is perror(NULL) when setlocale() fails,
and see if there's any useful error message.

Then, try
strace ./yourprog 2>&1 | grep locale
and see if that provides any information.

Jun 27 '08 #5

P: n/a
Steven Woody wrote, On 27/04/08 16:42:
On Apr 25, 11:55 pm, Antoninus Twink <nos...@nospam.invalidwrote:
>On 25 Apr 2008 at 7:37, Steven Woody wrote:
<snip>
>You're missing an argument.

Sorry, when I modified the original code to make it simple to show
you, I made some errors. But the original code is right and I did
supplied correct arguments.
This, of course, is why you should always copy and paste actual tested code.
Well, below is a correct version of the
code and I made it more simple to illustrate the problem:

#include <libintl.h>
The above header is not defined by the C standard, so it would have been
better if you provided an example which did not use it.
#include <locale.h>
#include <stdio.h>

int main( void )
{
printf( "Current locale is %s\n", setlocale( LC_ALL, NULL ) );

bindtextdomain( "hellonls", "/usr/local/share/locale" );
textdomain( "hellonls" );

const char* msg = gettext( "Hello, world!" );
The above three functions are not part of the C standard. It is possible
they are doing something to affect the results, so try again without
using them. If they are the problem then I suggest asking in a Linux
group or if that is your platform or possibly comp.unix.programmer.
if ( ! setlocale( LC_ALL, "en_US" ) )
fprintf( stderr, "setlocale( en_US ) error\n" );
I don't believe that errno is required to be set by setlocale, but it
might be worth replacing the above (and the other error printouts) with
calls to perror for testing just in case your implementation is helpful.
I.e.
perror( "setlocale( en_US ) error\n" );
printf( "%s\n", msg );

if ( ! setlocale( LC_ALL, "zh_CN" ) )
fprintf( stderr, "setlocale( zh_CN ) error\n" );
printf( "%s\n", msg );

if ( ! setlocale( LC_ALL, "" ) )
fprintf( stderr, "setlocale( \"\" ) error\n" );
printf( "%s\n", msg );

return 0;
}

I found only the 3rd invocation of setlocale( ... ) can be success,
that is, I can only set locale to the system default. The calling
lines with "en_US" and "zh_CN" failed and returned NULL. So if my
system has LC_ALL=en_US, the code will print three same lines of
"Hello, world!" in english on the stdout, and If I set the LC_ALL to
zh_CN before run the code, I will got three same lines of "Hello,
world!" in Chinese.

Could you please try the code and tell me what's wrong here? You may
need to change "zh_CN" to a suitable locale to you. Thanks.
Having removed the non-standard code and changed to supported locales it
works, so I suspect either one of the non-standard function calls is
breaking setlocale or you are selecting locales not supported on your
system. If you ask on a group dedicated to your implementation they may
be able to tell you how to check what locales are supported (you could
try the command "locale -a") and as I say if removing the non-standard
functions helps a group dedicated to your implementation may be able to
tell you why.
--
Flash Gordon
Jun 27 '08 #6

P: n/a
Steven Woody <na********@gmail.comwrites:
Sorry, when I modified the original code to make it simple to show
you, I made some errors. But the original code is right and I did
supplied correct arguments. Well, below is a correct version of the
code and I made it more simple to illustrate the problem:
<snip code>

The problem is not (now) the call to setlocale but the way your system
interprets the string it is passed. If you are using a POSIX system
(most Unix-like OSes) then post in comp.unix.programmer and you will
get access to lots of experts.

Here, the topic is standard C, and your problem is no longer with that
standard function but with what your system does with the string. The
only help you are likely to get here is from Antoninus Twink who is
single-handedly attempting to broaden the topicality here to include
other languages as well as Linux locale commands. Over in c.u.p you
will find lot of people who can help.

--
Ben.
Jun 27 '08 #7

P: n/a
On Apr 28, 2:08 am, Ben Bacarisse <ben.use...@bsb.me.ukwrote:
Steven Woody <narkewo...@gmail.comwrites:
Sorry, when I modified the original code to make it simple to show
you, I made some errors. But the original code is right and I did
supplied correct arguments. Well, below is a correct version of the
code and I made it more simple to illustrate the problem:

<snip code>

The problem is not (now) the call to setlocale but the way your system
interprets the string it is passed. If you are using a POSIX system
(most Unix-like OSes) then post in comp.unix.programmer and you will
get access to lots of experts.

Here, the topic is standard C, and your problem is no longer with that
standard function but with what your system does with the string. The
only help you are likely to get here is from Antoninus Twink who is
single-handedly attempting to broaden the topicality here to include
other languages as well as Linux locale commands. Over in c.u.p you
will find lot of people who can help.

--
Ben.
Yes, I think I am in wrong group. I will go to comp.unix.programmer.
Thanks.
Jun 27 '08 #8

This discussion thread is closed

Replies have been disabled for this discussion.