Sza*_*lcs 6 c macos locale posix macos-ventura
在 macOS 13.3.1 上,strtod()似乎不尊重使用设置的区域设置uselocale(),并且无法正确处理小数点/逗号。这是 macOS 中的错误吗?有解决方法吗?
这是一个测试程序,它演示了这一点printf()并scanf()尊重小数点设置,但strtod()事实并非如此。
#include <locale.h>
#include <xlocale.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
int main() {
double x;
const char *num = "12.3";
char *end;
// First we set the locale globally to something that uses decimal
// commas instead of decimal points.
const char *locname = setlocale(LC_ALL, "de_DE");
struct lconv *lc = localeconv();
if (strcmp(lc->decimal_point, ",")) {
/* If decimal point is not a comma, presumably because the requested
* locale was not available, report locale information and quit. */
fprintf(stderr, "setlocale() returned '%s', decimal point is '%s'\n",
locname ? locname : "NULL",
lc->decimal_point);
abort();
}
// In this locale, printf() uses decimal commas, and both scanf() and strtod()
// assume decimal commas when reading numbers. Thus when reading 12.3, both
// of these function stop reading as soon as they reach the '.' character.
printf("Using locale with decimal comma:\n");
x = 0.0;
printf("%g\n", 12.3);
sscanf(num, "%lf", &x);
printf("%g\n", x);
x = strtod(num, &end);
printf("%g\n", x);
// Now we set the numeric local to use decimal points in a thread-local manner
// using the non-standard uselocale().
locale_t c_locale = newlocale(LC_NUMERIC_MASK, "C", NULL);
assert(c_locale != NULL);
uselocale(c_locale);
// Now both scanf() and strtod() should be assuming a decimal point,
// and both should read 12.3 in full.
printf("\nUsing locale with decimal point:\n");
x = 0.0;
printf("%g\n", 12.3);
sscanf("12.3", "%lf", &x);
printf("%g\n", x);
x = strtod(num, &end);
printf("%g\n", x);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
macOS 10.14.6 上的输出符合我的预期:
Using locale with decimal comma:
12,3
12
12
Using locale with decimal point:
12.3
12.3
12.3
Run Code Online (Sandbox Code Playgroud)
macOS 13.3.1 上的输出:
Using locale with decimal comma:
12,3
12
12
Using locale with decimal point:
12.3
12.3
12
Run Code Online (Sandbox Code Playgroud)
请注意,strtod()读数没有超过小数点。
注意:这是因为它导致 igraph 测试套件失败而被发现的。问题报告在这里。