【问题标题】:Input of 2D array (-1 for end of row input, -2 for end of 2D array input) problem二维数组的输入(-1 表示行结束输入,-2 表示二维数组输入结束)问题
【发布时间】:2019-12-21 19:50:24
【问题描述】:

大家好,感谢您抽出宝贵时间回答,

在练习时我遇到了一个问题,我需要输入一个二维数组(矩阵)。在练习中,它说当我完成输入一行(以进入下一行)时我应该输入 -1,并输入 -2 表示矩阵输入完成。

我尝试做这样的事情,我可以在我的大部分练习中使用它,但它不起作用,我似乎找不到原因。这是我的代码:


#include <stdio.h>
#include <stdlib.h>

int main()
{
    int i,j,matrix[100][100];
    int m,n;

    for(i=0; i<100; i++) {
    for(j=0; j<100; j++)
    {

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

        if(matrix[i][j]==-2) {
                m=i+1;  //After I enter -2, the matrix dimensions should be 
                n=j-1;  // "m" and "n", but for some reason once I enter this
                        // if statement, "i" has to be incremented by 1 
                        // and "j" has  to be decremented by 1 for it to work

                i=1000; // i use this to get out of nested loop
            break;
        }
        if(mat1[i][j]==-1)
        {
            i++; // once the user inputs -1, I increase "i"(next row), 

            j=0; //and here I set the "column" count to 0


        }
    }

    }



    for(i=0; i<m; i++) {
        for(j=0; j<n; j++) {
            printf("%d ", matrix[i][j]);
        }
        printf("\n");
    }




    return 0;
}

所以,当我有这样的输入时:

1 2 3 -1
1 2 3 -1
1 2 3 -2

矩阵(打印在屏幕上)看起来像:

1 2 3 
0 1 2 
0 1 2

有谁知道为什么这不能按预期工作?好像没找到!

【问题讨论】:

  • 至少变量 i 在外循环和 if 语句中增加了两次。
  • 我应该如何从内循环跳转到矩阵的下一个“行”?

标签: c loops for-loop multidimensional-array scanf


【解决方案1】:

您的代码没有意义。

事实上,所有输入都在一个内部循环中处理。然而,这个内部循环会一直执行到-2 被输入。所以外循环是多余的。

在内部循环中,下一个“行”的迭代从1 开始

for(j=0; j<100; j++)
                ^^^
{
    //...

    if(mat1[i][j]==-1)
    {
        i++; // once the user inputs -1, I increase "i"(next row), 

        j=0; //and here I set the "column" count to 0
        ^^^^

    }

因为在 if 语句中将其设置为零后,它会在循环中增加。

请注意,通常一行的值的数量可能会有所不同。

当使用一个标记值时(并且在您的分配中甚至使用了两个标记值),它总是意味着输入可以包含可变数量的项目。您的程序应该正确处理这种情况。否则,您必须计算每行中输入值的数量,如果数字不同,则会发出错误。但这会使您的程序更加复杂。

您也忽略了-2 可以关注-1 的情况。

这是一个演示程序,展示了如何组织数据输入。

#include <stdio.h>

int main(void) 
{
    enum { N = 100 };
    int a[N][N] = { 0 };
    size_t m = 0, n = 0;

    for ( ; m < N; m++ )
    {
        size_t i = 0;
        int value = 0;

        for ( ; i < N && value != -1 && value != -2; i++ )
        {
            scanf( "%d", &value );

            if ( value != -1 && value != -2 ) a[m][i] = value;
            else break;
        }

        if ( n < i ) n = i;

        if ( value == - 2 )
        {
            if ( i != 0 ) ++m;
            break;
        }
    }

    for ( size_t i = 0; i < m; i++ )
    {
        for ( size_t j = 0; j < n; j++ ) printf( "%d ", a[i][j] );
        putchar( '\n' );
    }

    return 0;
}

如果输入是

1 2 3 -1
4 5 6 -1
7 8 9 -2

然后程序输出如下矩阵

1 2 3 
4 5 6 
7 8 9 

或者例如,如果输入看起来像

1 2 3 4 -1
5 6 -1
-2

那么输出就是

1 2 3 4 
5 6 0 0 

在程序中m 表示行数,n 表示结果矩阵中的列数。

【讨论】:

  • 此答案中的代码未能包含&lt;stdio.h&gt;
  • 这个答案中的代码检查scanf的返回值失败。
  • 当输入行超过分配的长度时,此答案中的代码无法识别,它会默默地继续到下一行,而不是警告用户。
  • 当输入包含的行数超过分配的行数时,此答案中的代码无法识别,并在不警告用户的情况下继续执行。
  • 使用 -1 和 -2 作为标记表明负数不是数组的正确数据,但代码是这个答案无法对负值执行任何错误处理。
【解决方案2】:

问题中的代码尝试使用以下语句控制ij

for(i=0; i<100; i++) {
for(j=0; j<100; j++)

还有这些陈述:

if(mat1[i][j]==-1)
    {
        i++; // once the user inputs -1, I increase "i"(next row), 
        j=0; //and here I set the "column" count to 0
    }

这些冲突。当输入“-1”时,后面的语句将j 重置为零,但随后程序控制流向内部for 循环的末尾。 for 循环,for(j=0; j&lt;100; j++),递增 j 并继续执行。现在j 是一,而不是您想要的零。

与其试图用两段不同的代码来控制ij,不如把它统一起来。您可以编写使用循环而不对 ij 进行调整的代码,并根据具体情况进行调整:

i = 0; j = 0;
do
{
    int input;
    scanf("%d", &input);

    if (input == -2)
    {
        // At the end of the matrix, record the dimensions and leave the loop.
        m = i+1;
        n = j;
        break;
    }
    else if (input == -1)
    {
        // At the end of a row, move to the start of the next row.
        ++i;
        j = 0;
    }
    else
    {
        // Otherwise, record a single element and move to the next element.
        matrix[i][j] = input;
        ++j;
    }
} while (1);

【讨论】:

  • 非常感谢您的帮助,对于新手来说很容易理解。我明白我在哪里犯了错误。再次感谢。 +1
  • @VladfromMoscow:当用 Apple LLVM 10.0.1 和 clang-1001.0.46.4 替换问题中的代码以代替其 for 循环时,在 macOS 10.14 上执行.6,并在给定问题中显示的输入时产生所需的输出。你到底认为什么是无效的?
  • @EricPostpischil 编译后的代码并不意味着有效的代码。:) 代码至少没有考虑原始数组的上限。此外,一行输入的数据数量可以因行而异。
  • @VladfromMoscow:这些投诉与 OP 提出的问题无关,不会使程序无效。它们相当于限制了它的有用性——它不能用于任意或不规则大小的数组——但该代码在 OP 打算用于的有限情况下是有效的。请记住,Stack Overflow不是代码编写服务 - 答案旨在回答特定问题,不一定提供完全重新设计的程序来解决所有潜在问题和教学提问者一次性全部关于编程。
  • @VladfromMoscow:这些约束是您添加的,不是 OP 要求的。而且,正如我所说,目的是回答 OP 的具体问题,而不是解决他们的所有问题并教他们有关编程的一切。
猜你喜欢
  • 2021-03-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-07
  • 1970-01-01
相关资源
最近更新 更多