无法在2D变量数组中使用scanf

时间:2019-11-27 14:42:53

标签: c arrays scanf

我有一个作业,要求我制作一个N * N数组,然后用从1到N ^ 2的数字填充该数组。之后,我必须检查数组是否是魔方,但这不是我的问题。我已经尝试了所有方法,但是无法填充数组。 scanf永远持续下去。

正如您在屏幕快照中看到的那样,在第一个scanf中,假设我按2并输入,变量n变为2,因此必须创建一个名为msquare [2] [2]的数组。但是,当涉及到第二个scanf时,某些功能将无法正常工作,并且让我永远打字。我真的很感谢您的帮助。另外,如果问题必须与指针相关联,请尝试尽可能多地进行解释,因为我仍然不熟悉它们并且无法完全理解它们。

这是一个例子:

int n;
int i;
int j;

scanf("%d", &n);

int msquare[n][n];   

for (i=0; i<=n; i++)
    {
        for (j=0; j<=n; j++){
            scanf("%d",msquare[i][j]);
        }
    }

2 个答案:

答案 0 :(得分:4)

您的代码中需要解决三个问题。

第一个是您不能基于未初始化变量创建数组!

例如,您不能执行以下操作:

int main() {
    int n;
    int m[n][n];
    return 0;
}

只需确保在数组声明之前初始化变量,如下所示:

int main() {
    int n = 2;
    int m[n][n];
    return 0;
}

由于您从n调用中获得了scanf的值,因此您可以简单地编写以下代码:

int main() {
    int n;
    scanf("%d", &n);
    int m[n][n];
    return 0;
}

但是如果scanf由于某种原因失败,您可能会遇到麻烦。 处理此问题的正确方法是检查scanf的值。

int main() {

    int n;

    if (sscanf("%d", &n) != 1) {
        printf("Failed to get a matrix size from stdin\n");
        return 1;
    }

    int m[n][n];

    return 0;
}

有时最好将变量初始化为一个合理的值。 在这种情况下,0是一个不错的选择。

int main() {

    int n = 0;

    if (scanf("%d", &n) != 1) {
        printf("Failed to get matrix size!\n");
        return 1;
    }

    int m[n][n];

    return 0;
}

虽然在某些情况下,使变量未初始化很有用,但这超出了此答案的范围。

此时最好添加检查以确保您的第一个输入变量不超过值8。

第二个问题是您的for循环。

您要循环执行一个额外的迭代。

例如,此代码:

int n = 2;
for (int i = 0; i <= n; n++) {
  printf("i = %d and n = %d\n");
}

打印:

0 2
1 2
2 2

看看效果如何,而不是2次?您应该使用<运算符而不是<=运算符来解决此问题。

您的循环(两者)都应该看起来像这样:

for (int i = 0; i < n; i++) {
    for (int j = 0; j < n; j++) {
    }
}

最后一个问题是您第二次致电scanf。此函数接受一个指针(就像您在第一个调用中所做的那样),但是您在第二个调用中向其传递了一个整数。

scanf("%d", m[i][j]);

您需要添加&使其成为指针。

scanf("%d", &m[i][j]);

修复这些问题,您的代码应该可以正常运行。

答案 1 :(得分:2)

请注意,C语言中的惯用for循环的形式为

for (int i = 0; i < maximum; i++)

(如果需要在循环外使用变量并事先定义变量,则可以省略int。)

该问题的某些版本包含scanf("%d", msquare[i][j]);,而没有&,有些版本包含scanf("%d", &msquare[i][j]);。带有&的版本是正确的。

解决了scanf()问题之后,您的循环使用了

for (i = 0; i <= n; i++)

引导代码访问数组的边界之外,从而对程序造成严重破坏。请记住:如果声明数组msquare[5][5],则可以访问元素msquare[0][0]msquare[4][4]-比4(或负索引)大的任何索引都将超出范围。自定义msquare[n][n]以来,您不得使用大于msquare[n-1][n-1]的任何东西,但是您的循环控件意味着您尝试访问msquare[n][n](写为msquare[i][j],但不能访问i == n || j == n时边界。

您正在调用不确定的行为,因此一切皆有可能。多种可能性之一是您用输入之一覆盖了n的值,因此它不是2而是变成38或您输入的任何内容,因此循环需要很多时间比您预期的更长。没有人可以确定正在发生的事情—未定义的行为可以做任何事情。但这是一个不合理的解释。