getline引起的SIGABRT错误(cin,s)

时间:2017-12-15 19:39:56

标签: c++ getline sigabrt

此代码在我的电脑上工作正常,但在线判断(Spoj)上显示SIGABRT。为什么?我认为问题在于getline它在我使用时被接受了:

input format: 52 + 81 = machula or 5machula + 81 = 133

string s1,s2,s3;
cin>>s1;
cin.ignore(3);
cin>>s2;
cin.ignore(3);
cin>>s3;

但我想先使用需要我使用getline的substr

string s,s1,s2,s3;
//cin.ignore(INT_MAX,'\n');
getline(cin,s);
int p1=0,p2,p3,l1,l2,l3;
l1=s.find("+")-1;
p2=s.find("+")+2;
l2=s.find("=")-s.find("+")-3;
p3=s.find("=")+2;
l3=s.length()-s.find("=")-2;
s1=s.substr(p1,l1);
s2=s.substr(p2,l2);
s3=s.substr(p3,l3);

1 个答案:

答案 0 :(得分:0)

the docs状态的输入规范:

  

输入文件的第一行包含一个指定测试用例数的整数T.每个测试用例前面都有一个空行。

OP尝试处理它可以概括为:

int t;
cin >> t;
cin.ignore(INT_MAX,'\n');
for(int u=0; u<t; u++)
{
    // ...
    std::string s;
    // cin.ignore(INT_MAX,'\n'); <-- another attempt
    getline(cin, s);
    // ... various operations involving s
}

这种方法的问题在于,当第一个ignore消耗流缓冲区中剩余的尾随换行符cin >> t;时,所有其他空行(仅由换行符组成的行)读取getline导致空字符串,以下代码无法处理此类字符串。

例如,当std::basic_string::find无法找到传递的子字符串时,它会返回std::basic_string::npos,其定义为

static const size_type npos = -1;

因此p2最终为1而调用s.substr(p2,l2);会引发std::out_of_range异常,因为我们正尝试从零大小的字符串中提取子字符串,从位置1开始。

添加注释掉的ignore行可以解决问题,但重写整个循环可能会更好:

int t;
std::cin >> t;

int u = 0;
while ( u < t )
{
    // ...
    std::string s;
    getline(cin, s);
    if ( s.empty() )
        continue;
    // ... various operations involving s
    ++u;
}