如果我将任何带有字符的double或整数作为最后一个vabiable e的输入,为什么.fail()
不起作用?
我为此问题添加了一些输出图片。
代码:
int main() {
string a,b,line;
double c;
int d,e;
stringstream ss;
getline(cin,line);
ss<<line;
ss>>a>>b>>c>>d>>e;
cout<<"command: "<<a<<endl<<"arg1: "<<b<<endl<<"arg2: "<<c<<endl<<"arg3: "<<d<<endl<<"arg4: "<<e<<endl;
if(ss.fail())
cout<<"Error: invalid command"<<endl;
else
cout<<"perfect"<<endl;
return 0;
}
如何解决此问题?
答案 0 :(得分:2)
>>
一旦找到无法解析为无法解析的数据类型的输入,就会停止读取。输入7.5读入int
是一个完全可以接受的7,而.5(不能是int
的一部分)留在流中,以便从流中读取下一个读取。如果OP为第三个参数(int d
)输入了7.5,则将.5读入第四个参数(int e
)将失败。
阿。完全忽略了如何修复部分。
我个人的偏好是以字符串形式读取所有数据并自行解析。在这种情况下,我会使用good ol' strtol
,主要是因为我没有因为不良用户输入而抛出异常的想法。错别字发生了。他们经常发生异常。处理它。
所以我们会读到std::string e
,而不是int e
,然后是......
char * endp; // strtol will point endp to character that ended the parsing.
// If that's not the end of the string there was stuff we couldn't parse
errno = 0; // clear the error code so we can catch an overflow error
// if the number parsed was too big
long num = std::strtol(e.c_str(), &endp, 10); // parse the string as a decimal number
if (*endp != '\0' || errno == ERANGE)
{
// handle error. Abort, nag user and repeat, whatever
}
// use num
OP已经补充说,他们不允许使用C库调用。就这样吧。 C++ library equivalent is std::stoi.我对上述例外的咆哮解释了为什么我不喜欢这个选项,但是我们走了!
size_t end;
int num = std::stoi(e, &end); // parse the string as a decimal number
if (end != e.length())
{
// handle error. Abort, nag user and repeat, whatever
}
// use num
如果完全无法转换,std::stoi
会抛出std::invalid_argument
。如果提供的数字太大,则会抛出std::out_of_range
,因此要么捕获并处理异常,要么让程序中止。你的电话。
答案 1 :(得分:0)
template< typename From,typename To>
static inline bool superConvert(const From& fromVar,To& toVar)
{
stringstream ss;
ss<<fromVar;
ss>>toVar;
if(ss.fail())
{
return false;
}
else
{
From tempFrom;
stringstream ss;
ss<<toVar;
ss>>tempFrom;
if(tempFrom != fromVar)
{
return false;
}
else
{
return true;
}
}
}
对于整数,此函数工作正常。由于它经过双重检查,正确的方法是使用stdol,但如果不允许,你可以使用它。
int i;
bool convertSuccess = superConvert<string,int>("25",i);
cerr<<i;