使用存在的问题与scanf函数时%i到拍摄日期(DD毫米YYYY) [英] Problems when using scanf with %i to capture date (mm dd yyyy)

查看:137
本文介绍了使用存在的问题与scanf函数时%i到拍摄日期(DD毫米YYYY)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在写计算经过的天两个日期之间的数字节目。要做到这一点,我必须输入的日期作为一个结构整数,像这样定义的:

I'm writing a program that calculates the number of elapsed days between two dates. To do this, I have to input the dates as integers in a structure defined like so:

struct date {
    int month;
    int day;
    int year;
};

现在,我已经想通了如何运行我的程序,但它确实烦我,用户不能输入的时候,月或日为单数(毫米DD YYYY)格式的日期。让我告诉你我的code(请不要介意调试的printf语句):

Now, I've figured out how to run my program, but it's really bugging me that the user can't input a date in (mm dd yyyy) format when the month or day are single digits. Let me show you my code (please don't mind the debug printf statements):

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

然后开始日期被记录为

Then the start date is recorded as

0/8/0

,它等于由用户输入的前三个数字。好吧,我理解这一点。我也明白,用户只需输入8 8 2004年,程序运行良好...但我相信节目是关于细节,这个人是开溜。谁能帮我解决这个问题?

Which is equal to the first three digits entered by the user. OK, I understand that. I also understand that the user can just enter "8 8 2004" and the program runs fine...but I believe programming is about details and this one is a bugger. Can anyone help me fix this?

推荐答案

使用%I 转换说明原因的 scanf()的 来解析输入,如果与strtol()调用了 0 作为基础参数。所以,既然 08 始于 0 8 是不是 X X ,它将该 08 作为一个八进制序列。但是,因为 8 是不是一个有效的八进制数,它停在那里,而结果是 0 将第一个数字

Using the %i conversion specifier causes scanf() to parse the input as if strtol() was called with 0 as the base argument. So, since 08 begins with a 0, and 8 is not an x or X, it treats the 08 as an octal sequence. But, since 8 is not a valid octal number, it stops there, and the result is 0 for the first number.

第二个号码,然后获取 8 ,因为它是由空格分隔。白色空间被跳过,第三个数字是解析 08 为八进制再次,致使 0 第三号。其余的 8 并在今年 2004年不被解析。

The second number then gets the 8, as it is delimited by whitespace. The white space is skipped, and the third number is parsing 08 as octal again, resulting in 0 for the third number. The remaining 8 and the year 2004 are not parsed.

使用%d个解析十进制数。

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

正如评论中提到, scanf()的一般应避免。作为替代方案,你可以使用与fgets()首先检索输入的整条生产线,并使用的sscanf()做解析。这样可以更好的错误恢复,因为一个错误可能由导致错误的行进行诊断,并线可以正常跳过为好。 scanf()的是为结构化的投入,只能给你发生扫描错误,其中一个大概的了解。而且,错误导致输入卡纸,从而导致混乱的调试会话的时间。

As mentioned in the comments, scanf() should generally be avoided. As an alternative, you could use fgets() to retrieve an entire line of input first, and use sscanf() to do parsing. This allows for better error recovery, since an error can be diagnosed by the line that caused the error, and the line can be gracefully skipped as well. scanf() is meant for structured input, and can only give you a rough idea of where a scanning error occurred. And, errors cause the input to jam, leading to confusing debugging sessions at times.

这篇关于使用存在的问题与scanf函数时%i到拍摄日期(DD毫米YYYY)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆