1

我想要做的是按照这种格式输入一个日期,Wednesday 7:05 PM然后将其分成令牌以放入我拥有的结构中。我的主要问题是我正在使用的 stringstream 对象没有从输入缓冲区中删除已经输入的字符串,所以在我第二次检查几个小时它失败了,因为它输入了 char 类型的东西到无符号中。我该如何解决?另外,如果您对我清理代码有任何建议,我将不胜感激。

struct Time{
        //  always in [0, 6]:
        //  0 means Sunday, 1 means Monday, ... , 6 means Saturday
    unsigned day;
        //  false means at or after midnight, and before the following noon (AM)
        //  true means at or after noon, and before the following midnight (PM)
    bool pm;
    unsigned hour;      //  in [1, 12], e.g. 12 for 12 o’clock
    unsigned minute;    //  in [0, 59]
};  //  struct Time

const string dayar[]={"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};

void input( Time & time ){
    string str, day, pm;
    unsigned hr, min;
    getline(cin,str);
    istringstream sin(str);
    cout<<str.length();
    for(unsigned i=0; i<str.length(); i++){
        if(str[i]==':')
            str[i]=' ';
    }
    if(!(sin>>day)){
        die("AHHHHH!!! WHERE'S THE INPUT?!?!?!");
    }else{
        for(unsigned i=0; i<7; i++){
            if(day==dayar[i]){
                time.day=i;
            }
        }
    }
    if(!(sin>>hr)){
        die("AHHHHH!!! WHERE'S THE INPUT?!?!?!");
    }else{
        if(hr<1 || hr>12){
            die("THAT NUMBER AIN'T A REAL HOUR!!");
        }else{
            time.hour=hr;
        }
    }
    if(!(sin>>min)){
        die("AHHHHH!!! WHERE'S THE INPUT?!?!?!");
    }else{
        if(min<0 || min>59){
            die("THAT NUMBER AIN'T A REAL HOUR!!");
        }else{
            time.minute=min;
        }
    }
    if(!(sin>>pm)){
        die("AHHHHH!!! WHERE'S THE INPUT?!?!?!");
    }else{
        if(pm!="PM" || pm!="AM"){
            die("THAT NUMBER AIN'T A REAL HOUR!!");
        }else{
            pm=="PM"?time.pm=true:time.pm=false;
        }
    }
}

bool die(const char *msg){
    cout<<msg;
    exit(EXIT_FAILURE);
}
4

2 回答 2

3

当您将冒号更改为空格时,您可以更改字符串,但您不会更改输入流缓冲的内容。

在声明输入流之前更改冒号。

此外,还有更好和更多的“C++-ish”方法可以做到这一点,例如std::transform

#include <algorithm>

// ...

std::transform(str.begin(), str.end(), str.begin(),
    [](const char c){ return (c == ':' ? ' ' : c); });
于 2012-09-20T05:09:01.940 回答
1

我不明白为什么您不会在一份声明中阅读这些值。像这样的东西:

// Map day names to day number
map<string,unsigned> days;
for( unsigned i = 0; i < 7; i++ ) days[dayar[i]] = i;

bool ParseTime( const string& str, Time& time )
{
    bool valid = false;
    istringstream sin(str);

    string day, pm;
    unsigned hour, minute;  // Because unsigned, we don't bother to test >= 0
    char colon;

    if( sin >> day >> hour >> colon >> minute >> pm )
    {
        // Sanity test...
        valid = (days.find(day) != days.end())
             && (hour >= 1 && hour <= 12)
             && (colon == ':')
             && (minute < 60)
             && (pm == 'AM' || pm == 'PM');
    }

    if( !valid ) return false;

    time.day = days[day];
    time.hour = hour;
    time.minute = minute;
    time.pm = (pm == 'PM');

    return true;
}

我的意思是,如果您想对每个可能的日期解析错误大喊大叫,那就继续吧!=) 但这只会导致难以理解的混乱代码。

于 2012-09-20T05:51:43.107 回答