我正在研究C ++。我正在编写日期格式的代码。使用with,我们可以从任何其他日期格式获取默认日期格式。所以我找到了240个日期格式来完成这项任务。所以M想要使用switch case和sscanf功能。每个案例都有sscanf功能来分隔日,月,年。所以我需要240个案例和240个sscanf功能。有没有什么方法可以避免很多swtich和sscanf?如果您有任何想法,请告诉我们。
case 0:
sscanf(tsdate.c_str(),"%2d/%2d/%4d",&day,&month,&year);
break;
case 1:
sscanf(tsdate.c_str(),"%2d-%2d-%4d",&month,&day,&year);
break;
case 2:
sscanf(tsdate.c_str(),"%2d %2d %4d",&day,&month,&year);
break;
case 3:
sscanf(tsdate.c_str(),"%2d/%2d/%2d",&day,&month,&year);
coryear(year);
break;
case 4:
sscanf(tsdate.c_str(),"%2d/%2d/%2d",&year,&month,&day);
coryear(year);
break;
如上所述,我想要放240个案例和240个sscanf。请让我知道如何避免很多案件。
答案 0 :(得分:3)
你无法避免切换案例,但你可以创建多个函数来避免sscanf:
void scanDayFirst(string format)
{
sscanf(tsdate.c_str(),format,&day,&month,&year);
break;
}
void scanMonthFirst(string format)
{
sscanf(tsdate.c_str(),format,&month,&day,&year);
break;
}
依旧.....
结果将如下:
case 0:
scanDayFirst("%2d/%2d/%4d");
case 1:
scanDayFirst("%2d-%2d-%4d");
case 2:
scanDayFirst("%2d %2d %4d");
case 3:
scanDayFirst("%2d.%2d.%4d");
答案 1 :(得分:2)
enum { ITEM_YEAR, ITEM_MONTH, ITEM_DAY, NUM_ITEMS };
struct date_format { char const *fmt; int items[NUM_ITEMS]; };
struct date_format const formats[] =
{ { "%2d/%2d/%4d", { ITEM_DAY, ITEM_MONTH, ITEM_YEAR } }
, { "%2d-%2d-%4d", { ITEM_MONTH, ITEM_DAY, ITEM_YEAR } }
/* etc. */
};
int parts[NUM_ITEMS]; /* Instead of year,month,day */
sscanf(tsdate.c_str(), formats[x].fmt,
&parts[formats[x].items[0]],
&parts[formats[x].items[1]],
&parts[formats[x].items[2]]);
如果您想跳过某个项目,或者添加额外的项目,可以将其扩展为ITEM_NONE,等等。
NB。如果这是C ++,那么考虑使用流输入而不是sscanf。
答案 2 :(得分:0)
而不是枚举所有情况,而是考虑使用自定义语言进行格式规范:
Date x = parseDate(user_input, "dd-mm-yyyy");
它将使函数更短,更容易记录和更容易使用,也提高了使用它的代码的可读性。这个想法是使用像
这样的代码yyyy ............. 4-digits year
yy ............... 2-digits year with automatic century computation
mm ............... 2-digits month
m ................ 1 or 2 digits month
dd ............... 2-digits day
d ................ 1 or 2 digits day
anything else .... mandatory character
一个简单的实现可能是
Date parseDate(const std::string& input, const std::string& format) {
const char *src = input.c_str();
const char *fmt = format.c_str();
int year=-1, month=-1, day=-1;
while (*fmt) {
if (!*src) throw invalid_date(input, format);
if (strncmp(fmt, "yyyy", 4) == 0) {
fmt += 4;
year = getInt(src, 4);
} else if (strncmp(fmt, "yy", 2) == 0) {
fmt += 2;
year = guess_century(getInt(src, 2));
} else if (strncmp(fmt, "mm", 2) == 0) {
fmt += 2;
month = getInt(src, 2);
} else if (fmt[0] == 'm') {
fmt += 1;
month = getInt(src, -1);
} else if (strncmp(fmt, "dd", 2) == 0) {
fmt += 2;
day = getInt(src, 2);
} else if (fmt[0] == 'd') {
fmt += 1;
day = getInt(src, -1);
} else {
if (src[0] != fmt[0]) throw invalid_date(input, format);
src++; fmt++;
}
}
if (*src || year == -1 || month == -1 || day == -1)
throw invalid_date(input, format);
return Date(year, month, day);
}
注意:未经测试