【问题标题】:How do I validate the last four characters in a string are in the range of 1900 and 2000?如何验证字符串中的最后四个字符是否在 1900 和 2000 的范围内?
【发布时间】:2018-12-12 02:59:01
【问题描述】:

如何验证字符串中的最后四位数字是否在 1900 和 2100 的范围内?我什至不需要确切的答案,但至少需要如何检查字符串中的数字。

string getDate()
{
    string date = "";
    cout << "\nEnter a date in military format (DDMMMYYYY) such as:\n"
         << "-- 13MAR1999 for March 13, 1999\n"
         << "-- 01APR2025 for April 1, 2025\n"
         << "-- Note: year must be between 1900-2100.\n"
         << "Entry --> ";
         cin >> date;
    while(date.length() > 9 || date.length() < 9)
    {
        cout << "\nInvalid entry, must be 9 characters.\n";
        getDate();
    }
    if (date[5] < 1 || date[5] > 2)
    {
        cout << "\nYear must be between 1900-2100.\n";
        getDate();
    }
    return date;
}

【问题讨论】:

  • 数字 1 和字符 '1' 之间有很大的区别。他们不是,我重复一遍,是不一样的。您可以从修复代码中的这个错误开始,以便它正确检查 1000-2999 的范围,然后一旦你弄清楚了,弄清楚如何调整对 1000-2100 的检查应该很容易。跨度>
  • 尝试在 '1' 和 '2' 周围加上单引号
  • @SamVarshavchik 我不会说它非常很大。 '1'1 之间的差异是 48 :)(在 ascii 编码中)
  • 你可以使用输入的字符串数据来表示纪元时间,就像这篇文章stackoverflow.com/questions/4137748/…一样。制作 1900 年和 2100 年的纪元时间表示,然后使用您的比较运算符
  • 你在这里经常调用,所以要小心!

标签: c++


【解决方案1】:

目前,您检查if (date[5] &lt; 1 || date[5] &gt; 2) 不是完全您想要的。大多数 C++(和 C)编译器都按照 ASCII 对其字符进行编码。所以字符'0'(经常)有一个整数值48,字符'1'(经常)有一个整数值49等等。

当前代码的另一个问题是递归。以下代码将无限循环、打印输出和递归。 (即使下一个日期条目有效,它也会继续循环。)

while(date.length() > 9 || date.length() < 9)
{
    cout << "\nInvalid entry, must be 9 characters.\n";
    getDate();
}

您可以在这里简单地使用 if 语句...并记住正确处理您的递归。 (即,您要确保返回 new getDate() 的结果。因此,return getDate();

与其使用一连串的if-语句,我建议先将字符串转换为数字,然后再检查它是否在范围内19002100

string getDate()
{

    std::string date = "01APR2021";  //  read date (or hard-code it)

    // perform checks


    if (date.length() != 9) // you can simplify your length check
    {
        // error message

        return getDate();  //  beware of your while-loop and recursion
    }

    std::string lastFour(date.end() - 4, date.end());  // substring of last four characters of date
    std::string::size_type noIntTrack;  // tracks the stoi finishing position

    int year = std::stoi(lastFour, &noIntTrack);  // converts the year to an integer

    if (noIntTrack != 4)  // if not 4 => unsuccessful conversion
    {                     //   e.g. maybe user entered 01APR20AA
        // error handling:
        //   noIntTrack should be 4 to signify successful conversion of all characters

        return getDate(); // recurse
    }

    if (!(1990 <= year && year <= 2100))  // check if year not in range
    {
        // handle year out of range

        return getDate();
    }

    // other checks (e.g. month/date?)
    // if (date is not good) { return getDate(); }

    // date is valid:
    // party
    return date;
}

【讨论】:

  • C++ 确实保证使用 ASCII,即使这是迄今为止最常见的情况。
  • 我还没有看到不使用 ASCII 的情况,但我已经对我的语言进行了一些对冲。
  • 尼特。建议if (noIntTrack != 4) {...} else if (1990 &lt;= year &amp;&amp; year &lt;= 2100) {...} else { /* handle out of range */ }.
  • @DavidC.Rankin 我已将解决方案更改为使用returns。 (还是)感谢你的建议。 :-)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-21
  • 1970-01-01
相关资源
最近更新 更多