使用逗号和点来表示十进制数

时间:2018-04-12 14:36:48

标签: c localization comma

我有一个非常具体的问题,并没有在其他地方找到解决方案。我正在开发一个小项目,我希望通过允许用户使用逗号或点输入价格来使其更加强大。所以我做了一个小功能,允许我这样做:

#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");它会正常工作。有什么想法吗?

2 个答案:

答案 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] = '.';