由于 getline(cin,s) 导致的 SIGABRT 错误

SIGABRT error due to getline(cin,s)

本文关键字:SIGABRT 错误 getline cin 由于      更新时间:2023-10-16

这段代码在我的电脑上工作正常,但在在线法官(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;

但是我想更早地使用substr,这需要我使用getline

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);

OP 尝试解决的问题的输入规范状态:

输入文件的第一行包含一个整数 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;
}