如何检查用户是否输入了正确格式的日期?

时间:2014-11-28 12:28:35

标签: c

如何检查用户是否已将日期写入正确的格式(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);

但这只是直接通过?

我做错了什么?

4 个答案:

答案 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”​​。