如何避免Switch Case& sscanf功能

时间:2014-03-15 05:13:33

标签: c++

我正在研究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。请让我知道如何避免很多案件。

3 个答案:

答案 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);
}

注意:未经测试