Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/146.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 标记字符串_C++_String_Struct_Stream_Token - Fatal编程技术网

C++ 标记字符串

C++ 标记字符串,c++,string,struct,stream,token,C++,String,Struct,Stream,Token,我要做的是按照这种格式输入一个日期星期三晚上7:05,然后将其分离成标记,放入我拥有的结构中。我的主要问题是,我使用的stringstream对象没有从输入缓冲区中删除已经输入的字符串,所以在我第二次检查数小时后,它失败了,因为它将char类型的内容输入到未签名的字符串中。我该如何解决这个问题?另外,如果你对我清理代码有任何建议,我将不胜感激 struct Time{ // always in [0, 6]: // 0 means Sunday, 1 mean

我要做的是按照这种格式输入一个日期
星期三晚上7:05
,然后将其分离成标记,放入我拥有的结构中。我的主要问题是,我使用的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);
}
结构时间{ //始终在[0,6]中: //0表示星期日,1表示星期一,…,6表示星期六 未签名日; //false是指在午夜或之后,以及第二个中午(上午)之前 //“真”是指中午或中午之后,以及下一个午夜(下午)之前 布尔总理; 未签名的小时;//在[1,12]中,例如12代表12点钟 未签名的分钟;//在[0,59]中 }; // 结构时间 const string dayar[]{“星期日”、“星期一”、“星期二”、“星期三”、“星期四”、“星期五”、“星期六”}; 无效输入(时间和时间){ 字符串str,日,下午; 未签名的hr,min; getline(cin,str); istringstream-sin(str); 库特){ 死(“啊哈!!!输入在哪里?!”); }否则{ 如果(hr12){ 死(“那个数字不是一个真正的小时!!”); }否则{ 时间。小时=小时; } } 如果(!(sin>>min)){ 死(“啊哈!!!输入在哪里?!”); }否则{ 如果(min59){ 死(“那个数字不是一个真正的小时!!”); }否则{ 时间。分钟=分钟; } } 如果(!(sin>>pm)){ 死(“啊哈!!!输入在哪里?!”); }否则{ 如果(pm!=“pm”| pm!=“AM”){ 死(“那个数字不是一个真正的小时!!”); }否则{ pm==“pm”?time.pm=true:time.pm=false; } } } bool die(const char*msg){
cout将冒号更改为空格时,可以更改字符串,但不会更改输入流缓冲的内容

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

此外,还有更好、更多的“C++-ish”方法,例如:

#包括
// ...
std::transform(str.begin()、str.end()、str.begin(),
[](常量字符c){return(c==':'?'':c);};

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

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

此外,还有更好、更多的“C++-ish”方法,例如:

#包括
// ...
std::transform(str.begin()、str.end()、str.begin(),
[](常量字符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;
}
//将日期名称映射到日期编号
地图日;
对于(无符号i=0;i<7;i++)天[dayar[i]]=i;
布尔解析时间(常量字符串和str、时间和时间)
{
bool valid=false;
istringstream-sin(str);
串日,下午;;
未签名的小时,分钟;//因为未签名,我们不必费心测试>=0
半结肠;
如果(sin>>天>>小时>>冒号>>分钟>>下午)
{
//健全测试。。。
有效=(天。查找(天)!=天。结束()

&&(hour>=1&&hour我不明白您为什么不在一条语句中读取值。类似这样的内容:

// 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;
}
//将日期名称映射到日期编号
地图日;
对于(无符号i=0;i<7;i++)天[dayar[i]]=i;
布尔解析时间(常量字符串和str、时间和时间)
{
bool valid=false;
istringstream-sin(str);
串日,下午;;
未签名的小时,分钟;//因为未签名,我们不必费心测试>=0
半结肠;
如果(sin>>天>>小时>>冒号>>分钟>>下午)
{
//健全测试。。。
有效=(天。查找(天)!=天。结束()

&&(hour>=1&&hour对此表示抱歉。感谢您指出这一点。我很抱歉您使用
?:
运算符获取AM或PM是不寻常的,通常它是这样使用的:
time.PM=(PM=“PM”)?true:false;
很抱歉。感谢您指出这一点。我很抱歉您使用
?:
运算符获取AM或PM是不寻常的,通常它是这样使用的:
time.PM=(PM=“PM”)?true:false;
我明白这就是为什么我在初始化istringstream后不久删除冒号并用空格替换它的原因。@NimaGanjehloo看到这一点太晚了。但是,用另一个问题更新了我的答案。啊,谢谢你指出:P我不太清楚转换的作用。我想我会尝试处理它b在我开始使用它之前。感谢你的建议tho。你知道如何从流中删除已经读取的w/e吗?这是唯一阻止此操作的原因:/@NimaGanjehloo我不确定你所说的“从流中删除已经读取的w/e”是什么意思?如果从流中读取了某些内容,则无法再次读取,除非您使用例如。我刚刚意识到我没有将字符串解析为下一个变量的正确数据类型。我明白这就是为什么在初始化istringstream后不久删除冒号并将其替换为空白。@NimaGanjehloo发现这一点太晚了。但是,更新了我的回答是另一个问题。啊,谢谢你指出:P我不太确定转换是做什么的。我想在开始使用它之前,我会尝试处理它。感谢你的建议tho。你知道如何从流中删除w/e吗?这是唯一阻止它工作的原因:/@NimaGanjehloo我不确定你所说的“删除已从流中读取的w/e”是什么意思?如果从流中读取了某些内容,则无法再次读取,除非您使用,例如…我刚刚意识到我没有将字符串解析为下一个变量的正确数据类型O_O…..太感谢了。这太干净了。感谢我所做的。实际上,在您发布此内容之前,我刚刚意识到我应该拥有pa