3

我正在编写一个程序来计算两个日期之间经过的天数。为此,我必须将日期作为整数输入到如下定义的结构中:

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”并且程序运行良好......但我相信编程是关于细节的,这个是一个错误。谁能帮我解决这个问题?

4

1 回答 1

6

使用%i转换说明符会scanf()解析输入,就好像作为基本参数strtol()调用一样。0因此,由于08以 a 开头0并且8不是xor X,因此它将 the08视为八进制序列。但是,因为8它不是一个有效的八进制数,所以它停在那里,结果是0第一个数字。

然后第二个数字得到8,因为它由空格分隔。空格被跳过,第三个数字08再次解析为八进制,导致0第三个数字。剩余8的和年份2004不被解析。

用于%d解析十进制数字。

scanf("%d %d %d", &startDate.month, &startDate.day, &startDate.year);

如评论中所述,scanf()通常应避免使用。作为替代方案,您可以使用fgets()先检索整行输入,然后使用sscanf()它进行解析。这允许更好的错误恢复,因为错误可以通过导致错误的行来诊断,并且也可以优雅地跳过该行。scanf()用于结构化输入,只能让您大致了解发生扫描错误的位置。而且,错误会导致输入卡顿,有时会导致调试会话混乱。

于 2013-05-10T01:41:58.697 回答