编写一个试图解析或编写基于文本的机器格式(经常发生)与C标准库函数的应用程序几乎不可能,如果您必须考虑将区域设置设置为不同于“C”的任何东西.由于locale通常是每个进程(并且setlocale通常不是线程安全的),如果你正在编写一个库或者你有一个多线程程序,即使做了setlocale(LC_ALL,“C”)也不安全,并在你做完之后恢复它东西.
现在,由于这些原因,规则通常是“避免setlocale,period”;但是:我们过去曾被QCoreApplication和派生类的特殊行为咬过几次; documentation说:
On Unix/Linux Qt is configured to use the system locale settings by default. This can cause a conflict when using POSIX functions,for instance,when converting between data types such as floats and strings,since the notation may differ between locales. To get around this problem,call the POSIX function
setlocale(LC_NUMERIC,"C")
right after initializingQApplication
orQCoreApplication
to reset the locale that is used for number formatting to “C”-locale.
此行为已在another question中描述;我的问题是:这种看似愚蠢的行为的理由是什么?特别是,Unix和Linux的特殊之处只能在这些平台上做出这样的决定?
(顺便说一句,如果我只是做setlocale(LC_ALL,“C”),一切都会破坏;创建QApplication之后?如果没关系,为什么不删除它们的setlocale(LC_ALL,“”);?)
解决方法
> XIM,至少在古代,没有这样的电话就没有正确地“获取”当前的语言环境.
>在Solaris上,它甚至崩溃了默认的C语言环境.
>在Unix系统上,它(在其他系统中,在复杂的回退游戏中)用于“嗅探”“系统字符集”(无论在Unix上是什么意思),因此能够在QString表示和“本地“8位编码(这对文件路径尤其重要).
确实它已经检查了LC_ *环境变量,就像它对QLocale一样,但是我认为如果应用程序明确地改变了它,那么让nl_langinfo解码当前的LC_CTYPE可能是有用的(但是看看是否有明确的改变,它必须从系统默认值开始).
有趣的是,他们在setlocale(LC_ALL,“”)之后立即执行了setlocale(LC_NUMERIC,但是this was removed in Qt 4.4.这个决定的理由似乎在于旧Qt bugtracker的任务#132859(它之间移动) TrollTech,诺基亚和QtSoftware.com在消失之前没有留下任何曲目,甚至在Wayback Machine中都没有,并且在two bugs中引用了有关此主题的内容.我认为关于这个主题的权威答案是存在的,但我找不到恢复它的方法.
我的猜测是它引入了微妙的错误,因为环境似乎是原始的,但实际上它被除了LC_NUMERIC类别之外的所有setlocale调用所触及(这是最明显的);可能他们删除了调用以使区域设置更明显,并让应用程序开发人员采取相应的行动.