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