6

有効な日付であることを確認するために日付を読み取る必要があるプロジェクトに取り組んでいます。たとえば、2 月 29 日はうるう年の有効な日付のみであり、6 月 31 日は有効な日付ではないため、コンピューターは入力に基づいてその情報を出力します。私の問題は、ユーザーが日付として「05/11/1996」を入力できるように文字列を解析する方法を理解できないことです(たとえば)。while ループと文字列ストリームで何とかしようと思っていたのですが、ちょっと行き詰まっています。誰かがこれで私を助けることができれば、本当に感謝しています.

4

4 に答える 4

14

考えられる解決策は にも基づいている可能性がありますがstrptime、この関数は、日が の間隔からのもので<1;31>あり、月が からのものであるかどうかのみを検証することに注意してください<1;12>。つまり、"30/02/2013"まだ有効です。

#include <iostream>
#include <ctime>

int main() {
    struct tm tm;
    std::string s("32/02/2013");
    if (strptime(s.c_str(), "%d/%m/%Y", &tm))
        std::cout << "date is valid" << std::endl;
    else
        std::cout << "date is invalid" << std::endl;
}
ただし、strptime常に利用できるとは限らず、追加の検証が必要な場合は、次のことができます。
  1. 日、月、年を抽出する
  2. 塗りつぶしstruct tm
  3. それを正規化する
  4. 正規化された日付が、取得した日、月、年と同じかどうかを確認します

すなわち:

#include <iostream>
#include <sstream>
#include <ctime>

// function expects the string in format dd/mm/yyyy:
bool extractDate(const std::string& s, int& d, int& m, int& y){
    std::istringstream is(s);
    char delimiter;
    if (is >> d >> delimiter >> m >> delimiter >> y) {
        struct tm t = {0};
        t.tm_mday = d;
        t.tm_mon = m - 1;
        t.tm_year = y - 1900;
        t.tm_isdst = -1;

        // normalize:
        time_t when = mktime(&t);
        const struct tm *norm = localtime(&when);
        // the actual date would be:
        // m = norm->tm_mon + 1;
        // d = norm->tm_mday;
        // y = norm->tm_year;
        // e.g. 29/02/2013 would become 01/03/2013

        // validate (is the normalized date still the same?):
        return (norm->tm_mday == d    &&
                norm->tm_mon  == m - 1 &&
                norm->tm_year == y - 1900);
    }
    return false;
}

使用されます:

int main() {

    std::string s("29/02/2013");
    int d,m,y;

    if (extractDate(s, d, m, y))
        std::cout << "date " 
                  << d << "/" << m << "/" << y
                  << " is valid" << std::endl;
    else
        std::cout << "date is invalid" << std::endl;
}

に正規化されているdate is invalidことを正規化が検出するため、この場合は出力されます。29/02/201301/03/2013

于 2013-10-20T20:41:06.087 に答える
5

フォーマットがあなたの例のようであれば、次のように整数を取り出すことができます:

int day, month, year;
sscanf(buffer, "%2d/%2d/%4d",
    &month,
    &day,
    &year);

もちろん、バッファには日付があります ("05/11/1996" )

于 2013-10-20T20:32:11.593 に答える