Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Using "setlocate()" to get the language

4 views
Skip to first unread message

CodHubIV

unread,
Sep 2, 2010, 12:16:46 PM9/2/10
to
Hello,

I'm writing some cross-platform software in C++, within it I have a
list of strings for various languages - My problem now is, how do I
determine the language setting of the person running the code so I can
present them information in the correct language? I'd rather not have
to resort to an entire framework just for this small function.

I tried "setlocale()" which always returns "C" on my Debian Lenny test
machine. I don't mind having slightly different functions for each OS
(I believe there are functions in the Windows API to determine
language, so that's taken care of), but I would like the Linux code to
work on all flavours of Linux, I see there's a "LANG" environmental
variable - Is this "safe" to rely on?

Code:

#include <iostream>
#include <locale.h>

int main()
{
// Get locale
char* value = setlocale(LC_ALL, NULL);

if (value == NULL)
std::cout << "NULL pointer returned" << "\n";
else
std::cout << "Value = \"" << value << "\"\n";
}

Result:

root@dev:./i18n
Value = "C"


Any help/advice from anyone who has tackled this before would be
appreciated...

Thanks,

Francesco S. Carta

unread,
Sep 2, 2010, 12:43:45 PM9/2/10
to
CodHubIV <codh...@gmail.com>, on 02/09/2010 09:16:46, wrote:

> Hello,
>
> I'm writing some cross-platform software in C++, within it I have a
> list of strings for various languages - My problem now is, how do I
> determine the language setting of the person running the code so I can
> present them information in the correct language? I'd rather not have
> to resort to an entire framework just for this small function.
>
> I tried "setlocale()" which always returns "C" on my Debian Lenny test
> machine. I don't mind having slightly different functions for each OS
> (I believe there are functions in the Windows API to determine
> language, so that's taken care of), but I would like the Linux code to
> work on all flavours of Linux, I see there's a "LANG" environmental
> variable - Is this "safe" to rely on?
>

I'm not an expert in the field but you shouldn't definitely rely on any
environment variable. If you can't get it right with the features
available in the standard libraries, the best pick, eventually, would be
to prompt the user for input.

Have a look at this in the meantime:
http://www.cantrip.org/locale.html

And don't forget this, just in case:
http://www.parashift.com/c++-faq/

More experienced people will eventually give further insight, just a
small further note from me:

> #include<locale.h>

If you really need to use C headers, use the form:

#include <clocale>

that is, remove the extension and add a "c" at the beginning of the
header name. <clocale> is part of the C++ standard library, <locale.h>
isn't.

--
FSC - http://userscripts.org/scripts/show/59948
http://fscode.altervista.org - http://sardinias.com

CodHubIV

unread,
Sep 2, 2010, 1:02:06 PM9/2/10
to
> I'm not an expert in the field but you shouldn't definitely rely on any
> environment variable. If you can't get it right with the features
> available in the standard libraries, the best pick, eventually, would be
> to prompt the user for input.

I'd hate for it to come to that, as this will be a stand-alone command-
line tool, so that would definitely impede it.

> Have a look at this in the meantime:http://www.cantrip.org/locale.html
>
> And don't forget this, just in case:http://www.parashift.com/c++-faq/

Thanks for that, I had a read through, it still hasn't given me any
more insight. Although the C++ FAQ looked an interesting read (just
in general, rather than to my current problem) so thanks.

> More experienced people will eventually give further insight, just a
> small further note from me:
>
> > #include<locale.h>
>
> If you really need to use C headers, use the form:
>
> #include <clocale>
>
> that is, remove the extension and add a "c" at the beginning of the
> header name. <clocale> is part of the C++ standard library, <locale.h>
> isn't.

I had a sudden panic after I read that, I thought it might be related
to me getting a "C" :-) (I changed it and it didn't effect the
program). Thanks for the advice on that though, I'll bear that in
mind in the future.

Thanks,

Vaclav Haisman

unread,
Sep 2, 2010, 1:02:55 PM9/2/10
to
CodHubIV wrote, On 2.9.2010 18:16:
> Hello,
>
> I'm writing some cross-platform software in C++, within it I have a
> list of strings for various languages - My problem now is, how do I
> determine the language setting of the person running the code so I can
> present them information in the correct language? I'd rather not have
> to resort to an entire framework just for this small function.
If you are writing cross-platform sofwtare then use cross-platform tool. It
is wrong to do it the way you want. Bite the bullet and use gettext as
everybody else on Linux. That is the right way how to do it on more than just
Linux.

> [...]

--
VH

Paavo Helde

unread,
Sep 2, 2010, 1:21:39 PM9/2/10
to
"Francesco S. Carta" <entu...@gmail.com> wrote in news:4c7fd43f$0$6824
$5fc...@news.tiscali.it:

>
> I'm not an expert in the field but you shouldn't definitely rely on any
> environment variable.

Why not? This is how the user can express their preference in a flexible
way, what's wrong with that?

Cheers
Paavo

Francesco S. Carta

unread,
Sep 2, 2010, 1:43:43 PM9/2/10
to

That must be some bad experience with Windows variables getting changed
randomly, I hope that Linux & co. are more affordable - told ya I wasn't
an expert ;-)

CodHubIV

unread,
Sep 2, 2010, 1:44:37 PM9/2/10
to
> If you are writing cross-platform sofwtare then use cross-platform tool. It
> is wrong to do it the way you want. Bite the bullet and use gettext as
> everybody else on Linux. That is the right way how to do it on more than just
> Linux.

Well, ideally I'd like a cross-platform standard way to get the
language - rather than a complete framework. I had a look at
"gettext" as you suggested, it just seems like overkill - It does seem
to handle all the language translation for you, tt also appears to
rely on placing the translation files in a certain location, rather
than building them into the project (creating a potential dependancy).

There also seems to be a few gotcha's running it on Windows:

http://supertuxkart.sourceforge.net/Gettext_on_windows

I like my applications to compile natively on both Linux (g++) and
Windows (VS.NET) with no porting, or having to use compilers like
mingw.


I only neeed to translate a few strings (http://code.google.com/p/
paping/wiki/Translation)


Is there not just a standard c++ function to retrieve the language,
I'd have thought this would be quite an important function.
'setlocale' looked it it fitted the bill but didn't.

CodHubIV

unread,
Sep 2, 2010, 1:46:05 PM9/2/10
to
> Why not? This is how the user can express their preference in a flexible
> way, what's wrong with that?

It did look like the way to go but I wasn't sure if it's universally
there (on all version of Linux, maybe BSD and MacOS as well later down
the line).

I'd be interested to know how 'gettext' works out the language
(internally). Then I guess I could rip that function out, rather than
having to implement the whole thing.

Francesco S. Carta

unread,
Sep 2, 2010, 1:54:36 PM9/2/10
to
CodHubIV <codh...@gmail.com>, on 02/09/2010 10:02:06, wrote:

>> I'm not an expert in the field but you shouldn't definitely rely on any
>> environment variable. If you can't get it right with the features
>> available in the standard libraries, the best pick, eventually, would be
>> to prompt the user for input.
>
> I'd hate for it to come to that, as this will be a stand-alone command-
> line tool, so that would definitely impede it.

Ah, yes, that would be a show-stopper for sure.

>> Have a look at this in the meantime:http://www.cantrip.org/locale.html
>>
>> And don't forget this, just in case:http://www.parashift.com/c++-faq/
>
> Thanks for that, I had a read through, it still hasn't given me any
> more insight. Although the C++ FAQ looked an interesting read (just
> in general, rather than to my current problem) so thanks.

Sorry if that wasn't all that helpful for this very case, at least I've
pointed out some resources which will come useful for the times to come,
eventually ;-)

>> More experienced people will eventually give further insight, just a
>> small further note from me:
>>
>>> #include<locale.h>
>>
>> If you really need to use C headers, use the form:
>>
>> #include<clocale>
>>
>> that is, remove the extension and add a "c" at the beginning of the
>> header name.<clocale> is part of the C++ standard library,<locale.h>
>> isn't.
>
> I had a sudden panic after I read that, I thought it might be related
> to me getting a "C" :-) (I changed it and it didn't effect the
> program). Thanks for the advice on that though, I'll bear that in
> mind in the future.

You're welcome, good luck with your project!

Francesco S. Carta

unread,
Sep 2, 2010, 2:17:57 PM9/2/10
to
Francesco S. Carta <entu...@gmail.com>, on 02/09/2010 19:43:43, wrote:

> Paavo Helde <myfir...@osa.pri.ee>, on 02/09/2010 12:21:39, wrote:
>
>> "Francesco S. Carta"<entu...@gmail.com> wrote in news:4c7fd43f$0$6824
>> $5fc...@news.tiscali.it:
>>>
>>> I'm not an expert in the field but you shouldn't definitely rely on any
>>> environment variable.
>>
>> Why not? This is how the user can express their preference in a flexible
>> way, what's wrong with that?
>
> That must be some bad experience with Windows variables getting changed

> randomly, I hope that Linux & co. are more affordable [...]
^^^^^^^^^^
change that with "reliable" - "reliable" != "affordable" but "reliable"
== "affidabile" in Italian... damned false friends...

James Kanze

unread,
Sep 5, 2010, 7:23:38 PM9/5/10
to

> Code:

> Result:

The problem is that there isn't just one "language" setting.
There are, or can be, many---in the past, I've often used a
different language setting for collating sequences than for
messages.

I don't have my C documentation handy to verify, but from
memory (probably wrong, but whatever), setlocale returns the
name of the previous locale---the first call should always
require "C". To get the user's locale, you should first do a
setlocale(LC_ALL, ""), and then recover the locale. But the
string isn't standardized, so you'll still end up with
implementation defined behavior when it comes to parsing it.

With regards to environment variables, the Unix conventions
establish a hierarchy: LC_MESSAGE (for messages), followed by
LC_ALL (if LC_MESSAGE isn't set), followed by LANG (if neither
LC_MESSAGE nor LC_ALL are set). But I think you'd be better off
setting the locale to the user defined value, then getting its
name. Or even better, install your messages so that they can be
found by the locale (but that's not always easy).

--
James Kanze

Jorgen Grahn

unread,
Sep 6, 2010, 1:59:25 PM9/6/10
to
On Thu, 2010-09-02, CodHubIV wrote:
...

> Is there not just a standard c++ function to retrieve the language,
> I'd have thought this would be quite an important function.
> 'setlocale' looked it it fitted the bill but didn't.

If you're referring to that it always said "C" when you tried it (in
your first posting) that must have been because you did something
wrong. Don't know *what* because I didn't read it, but people use
locales all the time.

(Stroustrup has a chapter on C++ locales from TC++PL for free
download, by the way. It's a bit better than the C/Unix API.)

/Jorgen

--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .

Geoff

unread,
Sep 6, 2010, 2:35:14 PM9/6/10
to
On Thu, 2 Sep 2010 09:16:46 -0700 (PDT), CodHubIV <codh...@gmail.com>
wrote:

>Hello,
>
>I'm writing some cross-platform software in C++, within it I have a
>list of strings for various languages - My problem now is, how do I
>determine the language setting of the person running the code so I can
>present them information in the correct language? I'd rather not have
>to resort to an entire framework just for this small function.
>
>I tried "setlocale()" which always returns "C" on my Debian Lenny test
>machine. I don't mind having slightly different functions for each OS
>(I believe there are functions in the Windows API to determine
>language, so that's taken care of), but I would like the Linux code to
>work on all flavours of Linux, I see there's a "LANG" environmental
>variable - Is this "safe" to rely on?
>
>
>
>Code:
>
>#include <iostream>
>#include <locale.h>
>
>int main()
>{
> // Get locale
> char* value = setlocale(LC_ALL, NULL);
>
> if (value == NULL)
> std::cout << "NULL pointer returned" << "\n";
> else
> std::cout << "Value = \"" << value << "\"\n";
>}
>
>

The standard specifies that the program's default locale is always the
"C" locale at startup.

Use char* value = setlocale(LC_ALL, NULL); to obtain the program's
current locale.

Use char* value = setlocale(LC_ALL, ""); to set the program's locale
to the system's default locale.

0 new messages