在C中获取二维数组的输入

时间:2014-02-15 00:26:26

标签: c arrays matrix scanf

我是一个完整的C初学者,刚刚开始一两周前,我主要使用“C:a Modern Approach”这本书,而且我真的,真的很挣扎指针, 我正在尝试编写一个函数来提示用户逐行输入矩阵,即用户输入第1行,按回车等等。

这是我到目前为止的代码:

    for(int (*p)[M] = &a[0][0]; p <= &a[N-1][M-1]; p++)
    {
        scanf("%d", p);
    }

在过去的5个小时里,我一直在努力解决这个问题,而且我看过很多网站,却找不到任何帮助。 新线的因素会影响到这个吗? scanf只是让我困惑。 是否可以修改此代码以避免用户输入矩阵的尺寸?它可以以某种方式检测新线字符吗?

我知道错误肯定是我对指针的理解,所以如果你有任何关于源的建议我可以用它来研究它们我会非常感激。 提前致谢。

1 个答案:

答案 0 :(得分:4)

在文件xx.c中给出以下代码(与您在问题中显示的内容非常接近):

#include <stdio.h>

int main(void)
{
  enum { M = 4, N = 5 };
  int a[N][M];

  for(int (*p)[M] = &a[0][0]; p <= &a[N-1][M-1]; p++)
  {
    scanf("%d", p);
  }
  return 0;
}

GCC 4.8.2编译器(在Ubuntu 12.04衍生版上运行)说:

$ gcc -g -O3 -std=c99 -Wall -Wextra -Werror -c xx.c
xx.c: In function ‘main’:
xx.c:8:21: error: initialization from incompatible pointer type [-Werror]
   for(int (*p)[M] = &a[0][0]; p <= &a[N-1][M-1]; p++)
                     ^
xx.c:8:33: error: comparison of distinct pointer types lacks a cast [-Werror]
   for(int (*p)[M] = &a[0][0]; p <= &a[N-1][M-1]; p++)
                                 ^
xx.c:10:5: error: format ‘%d’ expects argument of type ‘int *’, but argument 2 has type ‘int (*)[4]’ [-Werror=format=]
     scanf("%d", p);
     ^
cc1: all warnings being treated as errors
$

第一个错误是因为p是指向大小为M的数组的指针,但&a[0][0]只是指向int的指针。比较失败是类似的。你可以写:

for (int (*p)[M] = &a[0]; p < &a[N]; p++)

然后将scanf()错误解决。麻烦在于您将指向数组的指针传递给期望指向int的函数。此外,由于数组指针增量的工作方式,您尝试读取整行一行数据的一个数字。如果沿着这条路走下去,你需要一个嵌套循环:

    for (int *q = &(*p)[0]; q < &(*p)[M]; q++)
        if (scanf("%d", q) != 1)
            ...process data format error...

另一方面,您可以使用以下方法简化您的生活:

for (int *p = &a[0][0]; p < &a[N][M]; p++)
    if (scanf("%d", p) != 1)
        ...process data format error...

如果您需要使用指针(int),这是我建议您采取的路线。应尽可能避免使用数组指针,这几乎是所有时间。

这两个变体在这里被封装到一个程序中,以及使用数组索引的代码(由Jim Balter中的comment建议),这是最简单和最难出错的:

#include <stdio.h>

extern void error(const char *msg);

int main(void)
{
  enum { M = 4, N = 5 };
  int a[N][M];

  // Pointers to arrays - nasty
  for (int (*p)[M] = &a[0]; p < &a[N]; p++)
  {
    for (int *q = &(*p)[0]; q < &(*p)[M]; q++)
    {
      if (scanf("%d", q) != 1)
        error("Bother");
    }
  }

  // Pointers to int - OK
  for (int *p = &a[0][0]; p < &a[N][M]; p++)
  {
    if (scanf("%d", p) != 1)
      error("Bother");
  }

  // Array indices - can't go wrong easily!
  for (int n = 0; n < N; n++)
  {
    for (int m = 0; m < M; m++)
    {
      if (scanf("%d", &a[n][m]) != 1)
        error("Bother");
    }
  }

  return 0;
}