C scanf 意外地使用 %i 扫描日期
C scanf behaving unexpectedly with %i to scan dates
出于某种原因,当我 运行 我的程序时,它没有为我提供为与 day1 和 year2 关联的语句键入数字的选项。为什么要这样做?
#include <stdio.h>
int main(void ) {
int day1, day2, month1, month2, year1, year2;
printf("Enter date 1 mm\n");
scanf("%i", &month1);
printf("Enter date 1 dd\n");
scanf("%i", &day1);
printf("Enter date 1 yyyy\n");
scanf("%i", &year1);
printf("Enter date 2 mm\n");
scanf("%i", &month2);
printf("Enter date 2 dd\n");
scanf("%i", &day2);
printf("Enter date 2 yyyy\n");
scanf("%i", &year2);
return 0;
}
您需要 %d
将 int
作为 d 小数位输入。
scanf("%d", &year2);
您输入的是 08
还是 09
作为第一个 mm
值?
如果是这样,那就麻烦了:%i
转换规范在十六进制值之前接受 0x,在八进制值之前接受 0(参见 POSIX 规范中的 scanf()
)。如果您键入 08
或 09
,只有零作为八进制有效,因此它会在输入中留下 8 或 9,它们会立即被读取为 day1
值。同样,您可能为 day2
输入 08
或 09
,并且会发生相同的失败,因此 day2
包含 0 而 year2
包含 8 或 9。
您可以通过以下方式帮助自己和其他人:
- 正在检查
scanf()
调用是否成功。
- 打印从程序中输入的值。
- 包括节目的成绩单 运行ning.
例如:
#include <stdio.h>
int main(void ) {
int day1, day2, month1, month2, year1, year2;
printf("Enter date 1 mm\n");
scanf("%i", &month1);
printf("Enter date 1 dd\n");
scanf("%i", &day1);
printf("Enter date 1 yyyy\n");
scanf("%i", &year1);
printf("Enter date 2 mm\n");
scanf("%i", &month2);
printf("Enter date 2 dd\n");
scanf("%i", &day2);
printf("Enter date 2 yyyy\n");
scanf("%i", &year2);
printf("%.4d-%.2d-%.2d to %.4d-%.2d-%.2d\n",
year1, month1, day1, year2, month2, day2);
return 0;
}
样本运行:
$ ./date1
Enter date 1 mm
08
Enter date 1 dd
Enter date 1 yyyy
1999
Enter date 2 mm
12
Enter date 2 dd
09
Enter date 2 yyyy
1999-00-08 to 0009-12-00
$
该代码不检查 scanf()
调用,但它确实说明了您看到的行为。
修复
如果您希望数字是十进制的(即使有前导零),请使用 %d
而不是 %i
。
只有最勤奋的 C 程序员才能以八进制或十六进制输入日期。
出于某种原因,当我 运行 我的程序时,它没有为我提供为与 day1 和 year2 关联的语句键入数字的选项。为什么要这样做?
#include <stdio.h>
int main(void ) {
int day1, day2, month1, month2, year1, year2;
printf("Enter date 1 mm\n");
scanf("%i", &month1);
printf("Enter date 1 dd\n");
scanf("%i", &day1);
printf("Enter date 1 yyyy\n");
scanf("%i", &year1);
printf("Enter date 2 mm\n");
scanf("%i", &month2);
printf("Enter date 2 dd\n");
scanf("%i", &day2);
printf("Enter date 2 yyyy\n");
scanf("%i", &year2);
return 0;
}
您需要 %d
将 int
作为 d 小数位输入。
scanf("%d", &year2);
您输入的是 08
还是 09
作为第一个 mm
值?
如果是这样,那就麻烦了:%i
转换规范在十六进制值之前接受 0x,在八进制值之前接受 0(参见 POSIX 规范中的 scanf()
)。如果您键入 08
或 09
,只有零作为八进制有效,因此它会在输入中留下 8 或 9,它们会立即被读取为 day1
值。同样,您可能为 day2
输入 08
或 09
,并且会发生相同的失败,因此 day2
包含 0 而 year2
包含 8 或 9。
您可以通过以下方式帮助自己和其他人:
- 正在检查
scanf()
调用是否成功。 - 打印从程序中输入的值。
- 包括节目的成绩单 运行ning.
例如:
#include <stdio.h>
int main(void ) {
int day1, day2, month1, month2, year1, year2;
printf("Enter date 1 mm\n");
scanf("%i", &month1);
printf("Enter date 1 dd\n");
scanf("%i", &day1);
printf("Enter date 1 yyyy\n");
scanf("%i", &year1);
printf("Enter date 2 mm\n");
scanf("%i", &month2);
printf("Enter date 2 dd\n");
scanf("%i", &day2);
printf("Enter date 2 yyyy\n");
scanf("%i", &year2);
printf("%.4d-%.2d-%.2d to %.4d-%.2d-%.2d\n",
year1, month1, day1, year2, month2, day2);
return 0;
}
样本运行:
$ ./date1
Enter date 1 mm
08
Enter date 1 dd
Enter date 1 yyyy
1999
Enter date 2 mm
12
Enter date 2 dd
09
Enter date 2 yyyy
1999-00-08 to 0009-12-00
$
该代码不检查 scanf()
调用,但它确实说明了您看到的行为。
修复
如果您希望数字是十进制的(即使有前导零),请使用 %d
而不是 %i
。
只有最勤奋的 C 程序员才能以八进制或十六进制输入日期。