3

これは私が作成しなければならない非常に単純なプログラムですが、その方法については空白です。

基本的に、ユーザーは mm/dd/yyyy から日付を入力し、値を分離して別の行に出力するだけです。

これは私がこれまでに持っているものです:

int main ()
{
    char cMonth[2];
    char cDay [2];
    char cYear[4];

    cout << "Enter a date in the form mm/dd/yyy: " ;

    cin.get(cMonth,3,'/');
    cin.ignore(2,'/');
    cin.get(cDay, 4, '/');
    cin.ignore(2,'/');
    cin.get(cYear, 5);

    cout << cMonth << endl << cDay << endl << cYear << endl;
    return 0;
}

私のプログラムはコンパイルされますが、実行すると間違った出力が得られます。たとえば04/13/2013、出力を入れると次のようになります。

0413
13
2013
4

3 に答える 3

7

問題は、charバッファーがヌル ターミネーターを保持するのに十分な大きさではないため、バッファーの末尾を超えてヌル ターミネーターを記述していることです。cMonthとの場合cDay、スタックに隣接して格納されているため、明らかに互いに衝突します (その動作に依存しないでください!)。

少なくとも 1 バイト、つまり 3、3、および 5 バイト長くする必要があります。コードはバッファ オーバーフローに対して脆弱であることに注意してください。パラメータを調整して.get、バッファをオーバーフローさせたり、バッファを長くしたりしないようにすることができます。

于 2013-08-03T09:18:25.773 に答える
4

この種のことを行う別の方法は、単純に文字列全体を一度に読み取り、POSIX 標準関数strptime()を使用して、その部分を含む分解された構造体に変換することです。このような:

string in;
cin >> in; // TODO: check return value
struct tm out = {};
strptime(in.c_str(), "%m/%d/%Y", &out); // TODO: check return value
cout << out.tm_mon+1 << endl << out.tm_mday << endl << out.tm_year+1900 << endl;

のフィールドにstruct tmは「奇妙な」セマンティクスがあることに注意してください。そのため、整数オフセットがそのように適用されます。まあ、それを歴史にチョークで書きます。

パーツを印刷できるだけでなく、構造体を 、 などの他の関数に渡すことができstrftimeますmktime

于 2013-08-03T09:15:56.007 に答える
2

これを試して:

int main ()
{
    char cMonth[3];
    char cDay [3];
    char cYear[5];

    cout << "Enter a date in the form mm/dd/yyyy: " ;

    cin.get(cMonth,3,'/');
    cin.ignore(2,'/');
    cin.get(cDay, 4, '/');
    cin.ignore(2,'/');
    cin.get(cYear, 5);

    cout << cMonth << endl << cDay << endl << cYear << endl;
    return 0;
}
于 2013-08-03T09:18:17.160 に答える