同时使用逗号和点来表示十进制数
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);
}
(尽管来自另一个使用 ,
的国家/地区,我更愿意教育用户改用 .
形式,因为这更像是一个国际标准。有两个不同的标准世界各地的小数点对人类没有帮助。使用最少的版本应该适应。)
我遇到了一个非常具体的问题,并且没有在其他地方找到解决方案。我正在做一个小项目,我想通过允许用户使用逗号或点输入价格来使其更强大。所以我做了一个小功能可以让我这样做:
#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);
}
(尽管来自另一个使用 ,
的国家/地区,我更愿意教育用户改用 .
形式,因为这更像是一个国际标准。有两个不同的标准世界各地的小数点对人类没有帮助。使用最少的版本应该适应。)