我有一个非常具体的问题,并没有在其他地方找到解决方案。我正在开发一个小项目,我希望通过允许用户使用逗号或点输入价格来使其更加强大。所以我做了一个小功能,允许我这样做:
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
int main () {
setlocale(LC_ALL, "Portuguese");
float val;
char str[20];
scanf("%s", str);
for (int i = 0; str[i] != '\0'; ++i)
if (str[i] == ',')
str[i] = '.';
val = atof(str);
printf("String value = %s, Float value = %f\n", str, val);
return(0);
}
如果不是葡萄牙语,这将按预期工作。由于我们大多使用十进制数字的逗号,使用atof
函数不起作用,因为它转换为带点的浮点数,然后当我尝试printf
浮点数时它将显示0.0但是如果你删除行setlocale(LC_ALL, "Portuguese");
它会正常工作。有什么想法吗?
答案 0 :(得分:3)
有两个问题:
atof
这是一个永远不应该使用的不安全函数 - 它没有错误处理。请改用strtof
。您可以使用标准函数localeconv
获取有关当前区域设置的所有有用信息。
示例:
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
int main (void)
{
setlocale(LC_ALL, "Portuguese");
char ok_decimal_point = localeconv()->decimal_point[0];
char bad_decimal_point = (ok_decimal_point=='.') ? ',' : '.';
float val;
char str[20] = "123.456";
for (int i = 0; str[i] != '\0'; ++i)
{
if (str[i] == bad_decimal_point)
{
str[i] = ok_decimal_point;
}
}
val = strtof(str, NULL);
printf("String value = %s, Float value = %f\n", str, val);
return(0);
}
(虽然来自另一个使用,
的国家/地区,但我更倾向于教育用户使用.
表单,因为这更像是一个国际标准。对小数点有两个不同的标准世界各地都没有帮助人类。那些使用最少的版本应该适应。)
答案 1 :(得分:2)
您的代码按预期工作:
for
循环将所有,
转换为.
,因此atof
无法将.
的数字转换为小数点,因为您已调用{{1}事先。
你需要这个:
setlocale(LC_ALL, "Portuguese");
而不是:
if (str[i] == '.') str[i] = ',';
此示例清楚说明:
if (str[i] == ',') str[i] = '.';