c - 使 gzprintf 忽略区域设置 LC_NUMERIC

标签 c locale zlib

如何使 gzprintf (或一般的 printf)使用“.”作为小数点分隔符,有效地忽略 LC_NUMERIC 或使用“LC_NUMERIC = C”。

背景:我的程序使用 gettext ,执行 setlocale (LC_ALL, ....) 来更改其区域设置。但在某一时刻,我需要写入一个测量文件,该文件应该有一个固定的“.”。作为小数点分隔符。当然我可以做类似的事情

const char *old = setlocale (LC_NUMERIC, NULL);
... make copy
setlocale (LC_NUMERIC, "C");
... use gzprintf
setlocale (LC_NUMERIC, old_copy);

但我担心运行时问题,因为我必须将 2kHz 的样本写入文件,但尚未对其进行基准测试。

最佳答案

使用 setlocale 包装每个调用不仅可能会很慢。它完全是线程不安全的,因此在通用/库代码中使用是不安全的。

假设您使用的是 POSIX 或类 POSIX 系统,您需要的是 newlocale/uselocale。执行以下操作(可能会很慢)一次并保存结果:

locale_t safe_locale = newlocale(LC_NUMERIC_MASK, "C", duplocale(LC_GLOBAL_LOCALE));

然后,每当您想使用它时:

locale_t old = uselocale(safe_locale);
/* Do stuff with it. */
uselocale(old);

您不需要在每个操作之间来回切换,只需在返回到可能期望其区域设置不受干扰的调用者之前,但无论如何,像这样来回切换不应该很慢。

或者,根本不要在应用程序中使用 LC_NUMERIC。调用 setlocale(LC_ALL, "") 根据用户的设置设置区域设置后,调用 setlocale(LC_NUMERIC, "C") 并保持这种状态。这在库代码中是无效/ Not Acceptable ,但是如果您正在编写库代码,则可以让调用者负责执行它认为合适的任何方法(根本不尊重 LC_NUMERIC ,或者使用 newlocale/uselocale 进行切换)。您可以只在其契约(Contract)文档中写入此要求,并将未能履行契约(Contract)视为未定义,或者您可以通过断言 来主动测试非 '.' 基点localeconv()->decimal_point 指向字符串 "." (如果不成立,则返回错误或中止)。

关于c - 使 gzprintf 忽略区域设置 LC_NUMERIC,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53209751/

相关文章:

c++ - 可以在命令行参数中传递的最大字符串长度?

c - 为什么 fork() 返回值是 -1,为什么 wait() 退出状态不是 0?

java - 在 Jersey 请求中获取客户端语言环境

python - 协议(protocol)中的 CRC 计算不正确。一种是使用zlib实现的,另一种是用函数计算的

c - 从命令行参数C将十六进制转换为二进制

c - SIGTERM 信号处理程序未打印到控制台

java - Java如何确定 'file.encoding'系统属性?

c++ - boost::locale::date_time 的陷阱

java - 在 Linux 中使用 java.util.zip 压缩 SWF 时出现问题

makefile - zlib 构建没有使用交叉编译器正确配置,忽略 AR?