标记字符串

Tokenizing a String

本文关键字:字符串      更新时间:2023-10-16

我要做的是按照这种格式输入一个日期Wednesday 7:05 PM然后将其分成标记以放入我拥有的结构中。我的主要问题是我正在使用的字符串流对象不会从输入缓冲区中删除已经输入的字符串,因此在我第二次检查数小时时它失败了,因为它将 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);
}

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

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

此外,还有更好和更"C++"的方法可以做到这一点,例如使用 std::transform

#include <algorithm>
// ...
std::transform(str.begin(), str.end(), str.begin(),
    [](const char c){ return (c == ':' ? ' ' : c); });

我不明白为什么你不在一个语句中读取这些值。 像这样:

// 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;
}

我的意思是,如果你想对每一个可以想象的日期解析错误大喊大叫,那就继续吧! =) 但它只会使代码混乱,难以遵循。