c - 如何在 C 中通过 atof() 正确转换扫描的字符串?
问题描述
我需要验证通过 scanf() 传递的字符串只是数字和“。” 和“,”也应该可以接受,“-”作为负数表示。我写了这段代码:
int main(void)
{
char cFloatNum[100];
float fNum;
scanf("%[[+-]?[0-9]*[.,]?[0-9]+]", &cFloatNum);
fNum = atof(cFloatNum);
printf("%f", fNum);
return EXIT_SUCCESS;
}
0.000000
我不知道为什么,但无论我写什么数字,我的输出似乎总是如此。我尝试在各种正则表达式网站上测试我的正则表达式,它完美匹配。
向控制台写入内容后,如果有效,则应通过 printf 在控制台上打印。对于从字符串到浮点数的转换,我需要使用atof()
函数。
有效数字的示例是:
-44.276
44,546
56,657675
-77.2435235
解决方案
只有数字和“。” 和“,”也应该可以接受,“-”作为负数表示
所以就这么写吧。例如:
#include <stdio.h>
#include <ctype.h>
#include <stdbool.h>
int check_your_condition(float *result) {
int ret = 0;
*result = 0;
bool seen_minus = false;
bool first_character = true;
bool seen_dot = false;
float div = 10;
for (int c; (c = getchar()) != EOF; first_character = false) {
if (first_character == true && seen_minus == false && c == '-') {
seen_minus = true;
continue;
}
if (seen_dot == false && (c == '.' || c == ',')) {
seen_dot = true;
continue;
}
if (!isdigit((unsigned char)c)) {
ret = -1;
// TODO handle error properly
break;
}
const short num = c - '0';
if (seen_dot == false) {
*result *= 10;
*result += num;
} else {
const float numf = num / div;
div *= 10;
*result += numf;
}
}
if (seen_minus) {
*result *= -1;
}
return ret;
}
int main() {
float a;
check_your_condition(&a);
printf("%f\n", a);
}
这不是一个“即用型”(TM) 程序,因为多行上的换行符仍然只是在输入流中“忽略”(即isdigit(c)
会失败)。一个适当的解决方案应该ungetc
在那里调用,并包括正确的逻辑来处理其余的输入。
scanf("%[[+-]?[0-9]*[.,]?[0-9]+]"
是完全错误的。Noscanf
不支持正则表达式。
对于从 String 到 Float 的转换,我需要使用 atof() 函数。
很可能会要求您将输入作为单行读取,然后atof
在结果上应用函数:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
int main() {
char buf[200];
if (fgets(buf, sizeof(buf), stdin) == NULL) abort();
errno = 0;
const float a = atof(buf);
if (errno) abort();
printf("%f\n", a);
}
在这样的解决方案中,如果.
或,
将被理解为小数分隔符取决于语言环境。并且字符串后面的输入字符串部分将被忽略。
推荐阅读
- python - 如何在字符串中查找和删除日期时间,即:Sun Mar 3, 2019 07:39AM
- angular - 动态添加组件 ViewContainerRef 未定义
- javascript - 一旦客户端离开房间或断开连接,客户端不会重新连接
- jmeter - 我得到 java.net.URISyntaxException: Illegal character in query at index 220: while running a test in Jmeter
- ruby-on-rails - PG::ConnectionBad(致命:pg_hba.conf 拒绝主机“172.17.0.1”、用户“XXX”、数据库“XXX”、SSL 关闭):
- servlets - 如何将对象注入 groovy servlet?
- extend - 为什么我们不能在 vmware vSphere 云中使用快照扩展磁盘?
- ios - 如何删除 PersistentStore 并重新创建它以添加新数据?
- c# - MVC .net 控制器未从视图接收 POST 数据
- sql - 加入并获取另一个表中的最后一条记录