Reputation: 575
I'm doing the following to convert and check a date, however, I'm not sure why the following date keeps validating as true.
Wouldn't %d
check only for [01,31] + leading zeros
? Is there a better and more accurate way of doing this?
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
int main () {
struct tm tm;
char buffer [80];
char *str = "29/Jan/2012";
if (strptime (str, "%Y/%b/%d", &tm) == NULL)
exit(EXIT_FAILURE);
if (strftime (buffer,80,"%Y-%m-%d",&tm) == 0)
exit(EXIT_FAILURE);
printf("%s\n", buffer); // prints 29-01-20
return 0;
}
Upvotes: 10
Views: 3938
Reputation: 239041
It returns non-NULL because the initial substring 29/Jan/20
matches the pattern (in particular the 20
matches the final %d
in the pattern).
If strptime()
returns non-NULL
, it returns a pointer to the next character after the portion of the input string that matches the pattern. So, in this case, it will return a pointer to the '1'
character in the date string.
If you want to ensure that there's nothing left over in the input string, you need to check that the return value points to the terminating null at the end of the input string:
int main ()
{
struct tm tm;
char buffer [80];
char *str = "29/Jan/2012";
char *end = strptime(str, "%Y/%b/%d ", &tm);
if (end == NULL || *end != '\0')
exit(EXIT_FAILURE);
if (strftime (buffer,80,"%Y-%m-%d",&tm) == 0)
exit(EXIT_FAILURE);
printf("%s\n", buffer); // prints 29-01-20
return 0;
}
Note that I've added a trailing space to the strptime()
pattern - this allows trailing whitespace in the input to be accepted. If you don't want to allow that, use your original pattern.
Upvotes: 9