Невозможно определить ошибку во время выполнения в программе ниже - PullRequest
0 голосов
/ 12 февраля 2019

Я решал 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 голосов
/ 13 февраля 2019

cin >> t; не ест символ новой строки после прочтения числа 4 из ввода.Когда программа входит в цикл, cin.ignore() заканчивает первую строку ввода и затем getline(...) читает пустую строку.Вы получаете пустую строку, которая не может быть преобразована в целое число.

Установка еще одного 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;
}
0 голосов
/ 12 февраля 2019

Используя именно тот ввод, который вы опубликовали выше:

4

1 + 1 * 2 =

29 / 5 =

103 * 103 * 5 =

50 * 40 * 250 + 791 =

Я могу воспроизвести вашу ошибку:

завершить вызов после выброса экземпляра 'std :: invalid_argument'
what (): stoll
Прервано

Могу поспорить, что вы удалили символы новой строки в образце ввода, чтобы упростить вещи - вот как это выглядит из вашего кода в любом случае.Вы делаете getline и вытягиваете ровно столько строк, сколько указано в первом входе.Это означает, что вы вытянете пустую строку (intermediate будет пустой строкой) и попытаетесь ее обработать.

А что происходит, когда вы пытаетесь вызвать stoll("")?Полученная ошибка!

Вы могли бы попытаться проверить, получаете ли вы пустую строку, а затем продолжить, что-то вроде:

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

Или вы можете использоватьтот факт, что оператор >> уже останавливается при попадании в пробел (и съедает все пробелы, которые он может получить, чтобы перейти к следующему съедобному символу).Поэтому вместо чтения строки за раз вы можете продолжить чтение, пока не наберете символ =.

...