检查C中字符串的格式是否正确

我在函数中有以下代码来检查字符串’datestr’是否格式正确(dd / mm / yyyy):

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

虽然它使用正确的格式化字符串,如“02/10/2015”,它也适用于像“2/10/2015”这样的字符串,格式不正确,日期和月份必须是2位数字,每年4位数字.
有没有办法可以在sscanf函数中检查这个?
或者我必须先检查它,如下所示?

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

谢谢!

最佳答案 要使用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;

日期的各种测试,现代日期很容易.允许历史性日期很棘手. Feb 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;
}
点赞