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

Using both commas and dots to represent decimal numbers

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

#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] != '[=10=]'; ++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"); 它会工作得很好。有什么想法吗?

您的代码按预期工作:

for 循环将所有 , 转换为 .,因此 atof 无法转换以 . 作为小数点的数字,因为您调用了 setlocale(LC_ALL, "Portuguese"); 事先.

你需要这个:

if (str[i] == '.') str[i] = ',';

而不是这个:

if (str[i] == ',') str[i] = '.';

这个示例说明了这一点:

#include <stdio.h>
#include <stdlib.h>
#include <locale.h>

int main() {

  float val;

  // converting with default locale
  char str[20] = "1.234";
  val = atof(str);
  printf("Default locale: String value = %s, Float value = %f\n", str, val);

  // converting with Portugese locale    
  setlocale(LC_ALL, "Portuguese");

  char strport[20] = "1,234";
  val = atof(strport);
  printf("Portugese locale: String value = %s, Float value = %f\n", strport, val);
  return(0);
}

有两个问题:

  • 如果您遇到的小数点不是当前语言环境的正确小数点,那么并且只有在那时,才更改它。
  • 您正在使用 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] != '[=10=]'; ++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);
}

(尽管来自另一个使用 , 的国家/地区,我更愿意教育用户改用 . 形式,因为这更像是一个国际标准。有两个不同的标准世界各地的小数点对人类没有帮助。使用最少的版本应该适应。)