代码之家  ›  专栏  ›  技术社区  ›  Andy

使gzprintf忽略区域设置LC\u数值

  •  2
  • Andy  · 技术社区  · 6 年前

    我该怎么做 gzprintf (或printf)使用“.”作为十进制分隔符,实际上忽略LC\u NUMERIC或使用“LC\u 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的频率向文件中写入示例,但尚未对其进行基准测试。

    1 回复  |  直到 6 年前
        1
  •  3
  •   R.. GitHub STOP HELPING ICE    6 年前

    不仅是用 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") 就这样吧。这在库代码中是无效的/不可接受的,但是如果您正在编写库代码,您可以使用punt并让调用者负责执行它认为合适的任何方法(从不遵守) LC\ U数字 或者使用 / 使用区域设置 '.' localeconv()->decimal_point 指向字符串 "."