如何检查用户是否已将日期写入正确的格式(13/04/1995)
我试过这个
printf("\nPlease enter the patients date of birth in the form (03/04/2013): ");
if (sizeof(scanf("%d/%d/%d", &dob.day, &dob.month, &dob.year)) < 10)
{
printf("Error date needs to be in the format 03/04/2013.");
}
fflush(stdin);
但这只是直接通过?
我做错了什么?
答案 0 :(得分:0)
scanf
函数返回它读取的字段数,而不是字符数。 (另外,sizeof
没有按照你的想法做到。)
if (scanf("%d/%d/%d", &dob.day, &dob.month, &dob.year) < 3)
{
printf("Error date needs to be in the format 03/04/2013.");
}
然后,您必须以通常的方式检查日,月和年的范围。
编辑:显然,前导零是重要的。
scanf
读取数字,但比你想要的更宽松。然而,这不是一个迂腐的计划,而是如何呢?
if (scanf("%d/%d/%d", &dob.day, &dob.month, &dob.year) < 3)
{
printf("Error date needs to be in the format 03/04/2013.");
abort();
}
/* TODO: check the date is valid */
// Put the date into the proper format
char buffer[20];
sprintf (buffer, "%02d/%02d/%d", dob.day, dob.month, dob.year);
如果需要,printf
格式%02d
会写一个带前导零的两位数字。
答案 1 :(得分:0)
如果您使用POSIX系统(这就够了),请使用strptime()
来解析日期。否则你可以这样做,但请记住,返回值是成功转换的次数,而不是字符数。
答案 2 :(得分:0)
使用fgets()
将输入作为字符串读取到缓冲区。
然后使用strtok()
使用/
作为分隔符来中断输入。
您可以检查每个字符串的strlen()
以确保其格式正确。
将字符串转换为整数并相应地验证所有字符串。
答案 3 :(得分:0)
scanf("%d/%d/%d", ...)
返回成功扫描的int
个字段数 - 希望为3。
执行sizeof (int)
可能会返回4.
建议将整行读入缓冲区,然后将其解析为最佳方法。
char buf[100];
if (fgets(buf, sizeof buf, stdin) == NULL) Handle_IOErrorOrEOF();
解析缓冲区。
char sday[3];
char smonth[3];
char syear[5];
int n;
// Only allow limited number of digits
if (sscanf(buf, "%2[0-9]/%2[0-9]/%4[0-9]%n", day, month, year, &ch) != 3 ||
buf[n] != '\n' ||
n != 10) {
BadInput();
}
检查范围
int day = atoi(sday);
int month = atoi(smonth);
int year = atoi(syear);
// adjust as needed
#define YEAR_MIN 1910
#define YEAR_MAX 2099
if (year < YEAR_MIN || year > YEAR_MAX) BadInput();
// Could do other year, month, day tests or if code has robust time functions:
struct tm tm = { 0 };
tm.tm_year = year;
tm.tm_month = month;
tm.tm_mday = day;
// mktime() side effect: adjust y,m,d values if not in normal range
mktime(&tm);
if (tm.tm_year != year || tm.tm_month != month || tm.tm_mday != day) BadInput();
BTW:“(03/04/2013)”是一个很糟糕的例子,因为它不区分日/月。建议“31/01/2013”。