Статус выхода -1 в программе C ++ - PullRequest
0 голосов
/ 28 марта 2019

При выполнении мой код дает статус выхода -1. Я могу показать ввод, если это имеет какое-либо значение. Кто-нибудь может узнать, почему это происходит?

INPUT:

6

N 10

E 2

S 3

Ш 4

S 5

E 8

Я уже посмотрел на двумерный целочисленный массив и переменные в моем коде, ища неинициализированные, но я не нашел таких ошибок. Кто-нибудь может понять, почему я получаю статус выхода -1?

#include <iostream>
#include <algorithm>
#include <fstream>
using namespace std;

int main() {
  ofstream fout("mowing.out");
  ifstream fin("mowing.in");
  int n; fin >> n;
  int ans = 0;
  int field[2003][2003];
  for (int i = 0; i < 2003; i++) {
    for (int j = 0; j < 2003; j++) {
      field[i][j] = 0;
    }
  }
  int xloc = 1001, yloc = 1001, time = 0;
  for (int i = 0; i < n; i++) {
    char dir; int steps;
    fin >> dir >> steps;
    if (dir == 'N') {
      for (int j = 1; j < steps; j++) {
        yloc++;
        time++;
        if (field[xloc][yloc] != 0) ans = max(ans, time-field[xloc][yloc]);
        field[xloc][yloc] = time;
      }
    }
    if (dir == 'S') {
      for (int j = 1; j < steps; j++) {
        yloc--;
        time++;
        if (field[xloc][yloc] != 0) ans = max(ans, time-field[xloc][yloc]);
        field[xloc][yloc] = time;
      }
    }
    if (dir == 'W') {
      for (int j = 1; j < steps; j++) {
        xloc--;
        time++;
        if (field[xloc][yloc] != 0) ans = max(ans, time-field[xloc][yloc]);
        field[xloc][yloc] = time;
      }
    }
    else {
      for (int j = 1; j < steps; j++) {
        xloc++;
        time++;
        if (field[xloc][yloc] != 0) ans = max(ans, time-field[xloc][yloc]);
        field[xloc][yloc] = time;
      }
    }
  }
  if (ans == 0) fout << -1 << "\n";
  else fout << ans << "\n";
  return 0;
}

Ответы [ 3 ]

2 голосов
/ 28 марта 2019

в

fin >> dir >> steps;

вы не получите ожидаемые значения

первый ввод - int n; fin >> n;, и если входной файл подобен указанному в вопросе, первое значение для dir будет новой строкой (после 6 во входном файле), тогда >> окончательно останется в ошибке, ничего не делая, потому что после N не совместим с steps , являющимся int

Чтобы решить эту проблему

  • не должен смешивать int и char читать без уверенности в формате и явно обходить все необходимые символы
  • или гораздо более простой и безопасный способ - не читать char для dir , а только строку, поэтому string dir; вместо char dir; и, конечно, изменять тесты (dir == 'X') на (dir == "X") после, где X равно N , S или W

Возможно, вы пропустили добавление еще , потому что вы делаете:

if (dir == 'N') {
  ...
}
if (dir == 'S') {
  ...
}
if (dir == 'W') {
  ...
}
else {
  ...
}

так что последнее иначе обычно для случая 'E' также делается для случая N и S, вероятно, вы хотите

if (dir == 'N') { // in fact (dir == "N") see remark above
  ...
}
else if (dir == 'S') { // in fact (dir == "S") see remark above
  ...
}
else if (dir == 'W') { // in fact (dir == "W") see remark above
  ...
}
else {
  ...
}

Я рекомендую вам проверить, открываете ли вы файлы успешно, в настоящее время вы полагаете, что сделали, и проверить, хорошо ли вы прочитали во входном файле

Обратите внимание, что на моем raspberrypi размер стека ограничен 8192K (ulimit -s), поэтому размер поля слишком велик, я изменил его на static , чтобы иметь возможность выполнять программа (и я заменил сложную инициализацию, используя 2 для )

Каков ожидаемый контент для mowing.out ? При внесении изменений выше я получаю 18


Если я использую определение:

#include <iostream>
#include <algorithm>
#include <fstream>
using namespace std;

int main() {
  ofstream fout("mowing.out");

  if (!fout.is_open()) {
    cerr << "cannot open mowing.out" << endl;
    return -1;
  }

  ifstream fin("mowing.in");

  if (! fin.is_open()) {
    cerr << "cannot open mowing.int" << endl;
    return -1;
  }

  int n; 

  if ((!(fin >> n)) || (n < 0)) {
    cerr << "invalid number of couples" << endl;
    return -1;
  }

  int ans = 0;
  static int field[2003][2003] = { 0};
  int xloc = 1001, yloc = 1001, time = 0;

  for (int i = 0; i < n; i++) {
    string dir; int steps;

    if (!(fin >> dir >> steps)) {
      cerr << "error while reading fin & dir" << endl;
      return -1;
    }

    if (dir == "N") {
      for (int j = 1; j < steps; j++) {
        yloc++;
        time++;
        if (field[xloc][yloc] != 0) ans = max(ans, time-field[xloc][yloc]);
        field[xloc][yloc] = time;
      }
    }
    else if (dir == "S") {
      for (int j = 1; j < steps; j++) {
        yloc--;
        time++;
        if (field[xloc][yloc] != 0) ans = max(ans, time-field[xloc][yloc]);
        field[xloc][yloc] = time;
      }
    }
    else if (dir == "W") {
      for (int j = 1; j < steps; j++) {
        xloc--;
        time++;
        if (field[xloc][yloc] != 0) ans = max(ans, time-field[xloc][yloc]);
        field[xloc][yloc] = time;
      }
    }
    else {
      for (int j = 1; j < steps; j++) {
        xloc++;
        time++;
        if (field[xloc][yloc] != 0) ans = max(ans, time-field[xloc][yloc]);
        field[xloc][yloc] = time;
      }
    }
  }
  if (ans == 0) fout << -1 << "\n";
  else fout << ans << "\n";
  return 0;
}

Компиляция и исполнение:

pi@raspberrypi:/tmp $ g++ -g -pedantic -Wextra -Wall e.cc
pi@raspberrypi:/tmp $ cat mowing.in 
6

N 10

E 2

S 3

W 4

S 5

E 8
pi@raspberrypi:/tmp $ ./a.out
pi@raspberrypi:/tmp $ cat mowing.out 
18
1 голос
/ 28 марта 2019

Помимо превосходных замечаний, сделанных bruno, я считаю, что основной причиной проблемы, с которой вы столкнулись, является переполнение стека (nomen omen!).

Ваш массив слишком большой , чтобыпоместите в стек.Быстрые вычисления (при условии sizeof(int) == 4):

2003 * 2003 * 4 B = 16048036 B = 15671.91015625 KiB = 15.304599761962890625 MiB

Вы пытаетесь выделить 15,3 МБ памяти в стеке, тогда как, согласно этот вопрос , по умолчанию Windows допускает 1 МБа в Linux обычно разрешается 8 МБ.

Вы должны либо выделить память в куче самостоятельно, либо (лучше) использовать std::vector, например:

std::vector<std::vector<int>> field (2003, std::vector(2003));
//it is already initialized above, no need for for loops ;)
//later on it can be used like regular array in most of the cases
0 голосов
/ 28 марта 2019

Кто-нибудь может понять, почему я получаю статус выхода -1?

Не только кто-нибудь - Вы можете сделать это!

enter image description here

... с помощью отладчика для остановки вашей программы в разных точках во время ее выполнения и проверки значений n, ans и других переменных.

Я предполагаю, что вы используете IDE для редактирования и компиляции кода. В средах разработки обычно есть встроенные отладчики. Примеры:

Кажется, что учеников в наши дни действительно не учат отлаживать ... : - (

...