使用带有%i的scanf捕获日期时的问题(mm dd yyyy)
我正在编写一个计算两个日期之间经过的天数的程序。 为此,我必须在如下定义的结构中将日期作为整数输入:
struct date { int month; int day; int year; };
现在,我已经想出了如何运行我的程序,但是当月或日是单个数字时,用户无法以(mm dd yyyy)格式输入日期,这真让我烦恼。 让我告诉你我的代码(请不要介意调试printf语句):
printf("Enter your start date (mm dd yyyy)\n"); scanf("%i %i %i", &startDate.month, &startDate.day, &startDate.year); // DEBUG printf("Start date = %i/%i/%i\n", startDate.month, startDate.day, startDate.year); // DEBUG printf("start date month = %i", startDate.month); printf("Enter your end date (mm dd yyyy)\n"); scanf("%i %i %i", &endDate.month, &endDate.day, &endDate.year); // DEBUG printf("End date = %i/%i/%i\n", endDate.month, endDate.day, endDate.year);
如果用户输入:
08 08 2004
然后将开始日期记录为
0/8/0
这等于用户输入的前三位数字。 好的,我理解。 我也明白用户可以输入“8 8 2004”并且程序运行良好……但我相信编程是关于细节的,而且这个是一个bugger。 谁能帮我解决这个问题?
使用%i
转换说明符会导致scanf()
解析输入,就像调用strtol()
并将0
作为基本参数一样。 因此,从08
开始为0
,而8
不是x
或X
,它将08
视为八进制序列。 但是,由于8
不是有效的八进制数,它会在那里停止,第一个数字的结果为0
。
然后第二个数字得到8
,因为它是由空格分隔的。 跳过空白区域,第三个数字再次将08
解析为八进制,导致第三个数字为0
。 剩下的8
和2004
都没有解析。
使用%d
来解析十进制数字。
scanf("%d %d %d", &startDate.month, &startDate.day, &startDate.year);
正如评论中所提到的, 通常应避免使用scanf()
。 作为替代方案,您可以使用fgets()
来首先检索整行输入,并使用sscanf()
进行解析。 这允许更好的错误恢复,因为错误可以由导致错误的线路诊断,并且也可以优雅地跳过线路。 scanf()
用于结构化输入,只能让您大致了解扫描错误发生的位置。 并且,错误会导致输入阻塞,有时会导致调试会话混乱。