首页 > 解决方案 > 比较两个没有 strcmp() 和运算符重载的 c 样式字符串

问题描述

修改图 10.10 中的 Date 类,使其具有以下功能:

a) 以多种格式输出日期,例如:

  • DDD YYYY
  • 月/日/年
  • 1992 年 6 月 14 日

b) 使用重载的构造函数来创建使用 (a) 部分中格式的日期初始化的 Date 对象。

我陷入了这个问题的 b 部分;对于第三种格式,我创建了一个构造函数,它接收类型的数据char[]并创建一个数组 ( monthNames) 来保存月份名称,正如您在代码中看到的那样;但是在函数convert2(char[])中,比较不会发生。

有没有办法在没有运算符重载并且不使用函数的情况下比较这些字符串strcmp()

const int Date::days[monthPerYear + 1] = { -1, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };

const char* const Date::monthNames[monthPerYear + 1] =
{ "a", "January", "February", "March",
    "April", "May", "June",
    "July", "Agust", "September",
    "October", "November", "December" };

const int Date::daysPerMonth[monthPerYear + 1] =
{ 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };

Date::Date(int mn, int dy, int yr)
{
    if (mn > 0 && mn <= monthPerYear)
        month = mn;
    else
    {
        month = 1;
        cout << "Invalid month (" << mn << ") is set to '1'!" << endl;
    }

    year = yr;

    day = checkDay(dy);

    cout << "Date object constructor for date " << endl; 
    print(); 
    cout << endl;
}

Date::Date(int ddd, int yyyy)
{
    year = yyyy;
    convert1(ddd);

    cout << "Date object constructor for date " << endl;
    print();
    cout << endl;
}

Date::Date(char mn[], int dy, int yr)
{
    year = yr;
    day = dy;
    convert2(mn);

    cout << "Date object constructor for date " << endl;
    print();
    cout << endl;
}

Date::~Date()
{
    cout << "Date object destructor for date " << endl;
    print(); 
    cout << endl;
}

void Date::print() const
{
    cout << setfill('0') << setw(3) 
        << (year % 400 == 0 || (year % 4 == 0 && year % 100 != 0) ? (days[month] + day + 1) : (days[month] + day))
        << ' ' << setw(4) << year << endl;
    cout << setw(2) << month << '/' << setw(2) << day << '/' << year << endl;
    cout << monthNames[month] << ' ' << day << ", " << year << endl;
}

int Date::checkDay(int testDay) const
{
    if (testDay > 0 && testDay <= daysPerMonth[month])
        return testDay;

    if (testDay == 29 && month == 2 && (year % 400 == 0 || (year % 4 == 0 && year % 100 != 0)))
        return testDay;

    cout << "Invalid Day (" << day << ") is set to 1!" << endl;
    return 1;
}

void Date::convert1(int ddd)
{
    month = 0;

    for(int i = 1; (ddd - daysPerMonth[i]) > 0; i++)
    {
        if (i == 2 && (year % 400 == 0 || (year % 4 == 0 && year % 100 != 0)))
            ddd -= (daysPerMonth[i] + 1);
        else
            ddd -= daysPerMonth[i];

        ++month;
    }

    ++month;

    day = ddd;
}

void Date::convert2(char mn[])
{
    bool month;

    for (int i = 1; i < monthPerYear; i++)
    {
        month = true;

        for (int j = 0; j <= 2; j++)
        {
            if (mn[j] != *(monthNames[i] + j))
            {
                month = false;
                break;
            }
        }

        if (month)
        {
            month = i;
            return;
        }
    }

    month = 1;
}

标签: c++arrays

解决方案


如果您不允许使用strcmp或 c++ 字符串库,您可以自己执行原始循环:

bool string_compare(const char* a, const char* b)
{
    if (bool(a) != bool(b)) return false;
    if (!a && !b) return true;

    while (*a != '\0' && *b != '\0') {
        if (*a++ != *b++) return false;
    }

   return *a == *b;
}

或者,如果允许,您可以使用 memcmp:

bool string_compare(const char* a, const char* b)
{
    if (bool(a) != bool(b)) return false;
    if (!a && !b) return true;

   const auto a_size = std::strlen(a);
   const auto b_size = std::strlen(b);
   if (a_size != b_size) return false;

   return std::memcmp(a, b, a_size) == 0;
}

使用c++字符串库当然比上述任何一种方法都好

bool string_compare(const char* a, const char* b)
{
     return std::string(a) == std::string(b); //for c++11
     //return std::string_view(a) == std::string_view(b); //for c++17
}

推荐阅读