Check if the string matches the correct format in C

I have the following code in a function to check if the string 'datestr' is in the correct format (dd / mm / yyyy):

if (sscanf(datestr, "%d/%d/%d", &day, &month, &year) != 3) return NULL;

While it works with the correct formatted string, such as "02/10/2015", it also works with a string like "2/10/2015", which does not correspond to the correct formatting, as the day and month should be 2 digits every year and year 4 digits. Is there any way to check this in the sscanf function? Or do I need to check this earlier if the if condition looks like this?

if (!(strlen(datestr) == 10 && isdigit(datestr[0]) && isdigit(datestr[1]) && ...)) return NULL;

Thanks!

+4
source share
3 answers

sscanf(), "%[]" "%n".

// if (sscanf(datestr, "%d/%d/%d", &day, &month, &year) != 3) return NULL;
int n[3] = { 0 };
sscanf(datestr, "%*[0-9]%n/%*[0-9]%n/%*[0-9]%n", &n[0], &n[1], &n[2]); 
if (n[0] != 2 || n[1] != 5 || n[2] != 10) return NULL;

// Good To Go
sscanf(datestr, "%d/%d/%d", &day, &month, &year);

if (!ValidDate(year, month, day)) return NULL;

, - . . 30 1712 .?

,

int ValidDate(int year, int month, int day) {
  struct tm tm1 = { 0 };
  tm1.tm_year = year - 1900;
  tm1.tm_mon = month + 1;
  tm1.tm_mday = day;
  struct tm tm2 = tm1;
  if (mktime(&tm1) == -1) return 0; // failed conversion.
  // Did mktime() adjust fields?
  if (tm1.tm_year != tm2.tm_year) return 0;
  if (tm1.tm_mon != tm2.tm_mon) return 0;
  return tm1.tm_mday == tm2.tm_mday;
}
+2

, , sscanf. , . , , "% 2d/% 2d/% 4d" "100/10/2014", "1/10/2015".

, . . (.. , , 32 - ), . - std:: regex_match (++ 11 ). .

, .

  • , - . C, , . std:: regex_match ++, , , . (, posix regex), .
0

, , if, .

C, , , :

\d{2}\/\d{2}\/\d{4}

If you do not know how to use regex, see this link for compilation . You can find many C regex tutorials online, as well as for more complex algorithms.

0
source

Source: https://habr.com/ru/post/1612984/


All Articles