c++ - 为什么 scanf() 没有变成两个浮点数
问题描述
我是 C++ 的新手,我遇到了一些问题。要解决的问题是有 5 个输入,输入可以包括整数和字符串“none”,尝试对输入中的整数求和,结果应该是双精度数。这是我所做的:我在数组中放入了五个输入并使用 scanf() 将它们变成双精度,但是当我输入 none 并使用 printf 查看数组时,我发现它变成了两个浮点数,scanf将字符串转换为双精度有任何限制吗?
这是代码:
int main()
{
double sc[5];
for (int i = 0; i < 5; i++) {
sc[i] = 3;
scanf("%lf", &sc[i]);
printf("%lf\n", sc[i]);
}
}
输出是:
34
34.000000
none
3.000000
3.000000
56
56.000000
89
89.000000
解决方案
当且仅当输入是有效的浮点数时,调用scanf("%lf", &something)
才会填充。something
该字符串none
不是一个有效的数字。
你得到两个3
值的原因可能是因为nan
它是一个有效的浮点数,所以scanf
找到n
并说“哈,这将是一个nan
”。但随后它发现,令其失望的是,o
并决定它不再有效。
但它已经no
从输入流中读取了。然后它返回并与ne
(a)做同样的事情。
在那之后,你开始再次给它有效的数字,让它继续。
如果您希望能够处理字符串和数字,您将不得不使用限制最少的(字符串)然后再决定。像这样的东西(虽然scanf("%s")
对真正的代码很危险,但对课堂作业来说可能没问题):
以下代码执行此操作并(如您应该)检查返回值scanf/sscanf
以确保它被正确扫描:
#include <stdio.h>
#include <string.h>
int main() {
static char bigstring[1000];
double sc[5];
for (int i = 0; i < 5; i++) {
sc[i] = 3;
if (scanf("%s", bigstring) != 1) {
puts("*** Could not get input");
return 1;
}
if (strcmp("none", bigstring) == 0) {
puts("Got 'none', converting to -999");
sc[i] = -999;
} else if (sscanf(bigstring, "%lf", &sc[i]) != 1) {
printf("*** Could not convert input '%s' to float", bigstring);
return 1;
} else {
printf("Got %f\n", sc[i]);
}
}
puts("\nThe five entered numbers were:");
for (int i = 0; i < 5; i++) {
printf(" %lf\n", sc[i]);
}
}
使用基本测试数据正常运行:
pax:~$ printf "34\nnone\n56\n89\n111\n" | ./qq
Got 34.000000
Got 'none', converting to -999
Got 56.000000
Got 89.000000
Got 111.000000
The five entered numbers were:
34.000000
-999.000000
56.000000
89.000000
111.000000
(a)有趣的是,这似乎只发生在真实的用户输入中,而不是按照我的printf
陈述通过程序传输数据。
在我看来,理想的行为是让输入流指向无效数据。换句话说,除非确切的文本是有效的(如nan
),否则指针根本不应该移动。但是,C 标准中有一个脚注允许这种行为,例如,如果输入流不可搜索:
fscanf
将最多一个输入字符推回输入流。
因此,虽然它可能能够比管道上的备份更远,但在处理终端输入时可能并非如此。
当我x
作为输入输入时,它似乎确实将其推回,因为后面的每个数组元素都填充了3
,这意味着它正在x
连续读取它。任何以 an 开头的东西n
似乎只消耗那个和下面的字符。
推荐阅读
- python - 如何使用 pyglet 创建 3D?
- python - 根据列值将行拆分为多行
- python - 使用 folium 为特定国家绘制世界等值线图时出错
- php - 如何翻译 symfony 表单错误信息?
- java - 如何让代码等待所有请求完成 Android okhttp
- c++ - 在字符串中输入换行符
- python - How to iterate this n dimensional array?
- iso8583 - difference between iso8583 authorize request and authorize advice request
- ruby-on-rails - Ruby On Rails - "OpenSSL::Cipher::CipherError at ..." when connecting to imported database
- python-3.x - How to improve SpaCy matcher pattern