0

执行时,我的代码给出退出状态-1。如果有任何不同,我可以显示输入。任何人都可以找到为什么会这样吗?

输入:

6

氮 10

E 2

3

W 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;
}
4

3 回答 3

2

fin >> dir >> steps;

你没有得到预期值

第一个输入是int n; fin >> n;,如果输入文件就像您在问题中指出的那样,dir的第一个值将是换行符(在输入文件中的 6 之后),那么>>肯定会在不做任何事情的情况下保持错误,因为在没有N之后与作为int的步骤兼容

为了解决这个问题

  • 在不确定格式并明确绕过所有必要字符的情况下,不要混合读取intchar
  • 或者更简单、更安全,不要为dir读取char而是读取字符串,因此当然不要在XNSW之后更改测试string dir;char dir;(dir == 'X')(dir == "X")

可能您错过了添加其他内容,因为您这样做了:

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

所以通常情况下“E”的最后一个else也适用于 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),因此字段大小太大,我将其更改为静态以便能够执行程序(并且我使用 2 for替换了复杂的初始化)

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
于 2019-03-27T22:41:36.020 回答
1

除了 bruno 提出的优秀观点之外,我相信您遇到的问题的根本原因是(nomen omen!)堆栈溢出。

您的数组太大而无法放在堆栈上。快速计算(假设sizeof(int) == 4):

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

您正在尝试在堆栈上分配 15.3 MiB 的内存,而根据这个问题,默认情况下 Windows 允许 1 MiB,而 Linux 通常允许 8 MiB。

您应该自己在堆上分配内存或(更好地)使用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
于 2019-03-27T23:01:52.837 回答
0

任何人都可以看到为什么我得到退出状态-1?

不只是任何人——可以做到!

在此处输入图像描述

...通过使用调试器在程序执行期间的不同点停止程序并检查和其他变量n的值。ans

我假设您正在使用一些 IDE 来编辑和编译您的代码。IDE 通常具有集成的调试器。例子:

似乎这些天的学生真的没有被教导调试...... :-(

于 2019-03-27T23:20:47.437 回答