无法在以下程序中找出运行时错误

时间:2019-02-12 20:11:12

标签: c++ algorithm sigabrt

我正在解决ArithmaticII。我得到以下输入的正确输出

输入: 4

1 +1 * 2 =

29/5 =

103 * 103 * 5 =

50 * 40 * 250 + 791 =

输出:

4

5

53045

500791

我得到正确的输出,但是当我将解决方案提交给spoj时,我 出现SIGABRT的运行时错误,由于溢出问题,我正在使用stoll,当我尝试调试程序时,一切似乎都运行良好。

注意->它可能还包含空格以提高可读性。

这行对我来说可疑,因为当我不提供程序时,我的程序就会停止(运行时错误) 输入中的空格(1 * 1 + 2 =) terminate called after throwing an instance of 'std::invalid_argument' what(): stoll 请帮我哪里做错了吗?

#include<iostream>
#include<string>
#include<sstream>
using namespace std;
int main() {
    int t;
    string str;
    cin >> t;

    while (t--) {


        ///using cin.ignore() as input as preceded by a single line  
        cin.ignore();
        getline(cin, str, '\n');
        stringstream split(str);
        ///now use getline with specified delimeter to split string stream
        string intermediate;
        int flag = 0;
        long long int ans=1;
        while (getline(split, intermediate, ' ')) {
            if (intermediate == "=") {
                cout << ans<<"\n";
                break;

            }
            if (intermediate == "*") {
                flag = 1;
                continue;
            }
            else if (intermediate == "/") {
                flag = 2;
                continue;
            }
            else if (intermediate == "+") {
                flag = 3;
                continue;
            }
            else if(intermediate == "-"){
                flag = 4;
                continue;
            }
            if (flag == 1) {
                ans *= stoll(intermediate);
            }
            else if (flag == 2) {
                ans /= stoll(intermediate);
            }
            else if (flag == 3) {
                ans += stoll(intermediate);
            }
            else if (flag == 4) {
                ans -= stoll(intermediate);
            }
            else if (flag == 0) {
                ans = stoll(intermediate);
            }

        }
    }
}

2 个答案:

答案 0 :(得分:0)

完全使用您在上面发布的输入内容:

4

1 + 1 * 2 =

29 / 5 =

103 * 103 * 5 =

50 * 40 * 250 + 791 =

我能够重现您的错误:

  

在抛出'std :: invalid_argument'实例后调用的终止
   what():斯托尔
  中止

我敢打赌,您删除了示例输入中的换行符以简化操作-无论如何,这就是代码中的样子。您正在执行getline,并按照第一个输入中的提示完全拉出许多行。这意味着您将拉空行(intermediate将为空字符串),并尝试对其进行处理。

当您尝试致电stoll("")时会发生什么?您收到的错误!

可以尝试检查是否出现空白行,然后继续操作,例如:

getline(cin, str, '\n');
if(str.empty()) {
    t++; //we didn't actually do anything, so increment t
    continue;
}
stringstream split(str);
...

或者,您可以使用以下事实:>>运算符在到达空格时已经停止(并且吃掉了所有可以到达下一个可食用字符的空格)。因此,您可以继续阅读,直到您碰到=字符,而不是一次阅读一行。

答案 1 :(得分:0)

cin >> t;在从输入中读取数字4后不吃换行符。程序进入循环时,cin.ignore()完成输入的第一行,然后getline(...)读取空白行。您将获得一个空字符串,该字符串无法转换为int。

在读取cin.ignore()之后再插入t可以解决运行时错误。

当令牌之间没有空格时,您仍然必须处理这种情况。这需要重新考虑内部的while循环:

long long int ans;
char op;
split >> ans;
while (split >> skipws >> op) {
    if (op == '=') {
        cout << ans << '\n';
        break;
    }
    long long int n;
    split >> n;
    if (op == '*')
        ans *= n;
    else if (op == '/')
        ans /= n;
    else if (op == '+')
        ans += n;
    else if(op == '-')
        ans -= n;
}