【问题标题】:Why is my function incorrectly returning part of my 2D array? [closed]为什么我的函数错误地返回了我的二维数组的一部分? [关闭]
【发布时间】:2020-02-17 23:50:51
【问题描述】:

我正在编写一个程序,该程序需要读取地图文件并将数据保存为 2D int 数组。数据格式为:

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

我能够读取所有数据并将其正确存储在我的 main 方法中,但我想稍微清理一下我的代码,所以我尝试编写一个函数来打开文件、读取数据、创建一个静态数组,然后返回一个指向它的指针。问题是当我尝试打印返回的数组时,它会打印第一行中每一行的第一个索引,然后每隔一行打印一堆零。我尝试了几种不同的方法来取消引用单个索引,一旦我在 readMap() 函数之外引用它,我的数组似乎会发生变化,但我不知道为什么会发生这种情况。到目前为止,这是我的代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BUFFER_SIZE 20
typedef int MAP_ARRAY[9][9];

MAP_ARRAY * readMap(const char *fileName);

int main (int argc, char *argv[]) {

    MAP_ARRAY *map;
    map = readMap(argv[1]);
    for(int i = 0; i<9; i++){
      for(int j = 0; j<9; j++){
        printf("%d ", *map[i][j]);
      }
      printf("\n");
    }
    exit(EXIT_SUCCESS);

}

MAP_ARRAY* readMap(const char *fileName){
    FILE *mapFile;
    char *line = NULL;
    size_t buffSize = BUFFER_SIZE;
    size_t numChars;
    static MAP_ARRAY returnMap;
    mapFile = fopen(fileName,"r");

    if(mapFile == NULL){
      printf("Failed to open file.");
        exit(EXIT_FAILURE);
    }
    // Allocate space for line buffer
    line = (char *)malloc(buffSize * sizeof(char));
    int currLine = 0;
    while((numChars = getline(&line, &buffSize, mapFile)) != -1 && currLine < 9){
      char* token = strtok(line, ",");
      int input;
      int currIndex = 0;
      while(token != NULL && currIndex < 9){
        input = atoi(token);
        returnMap[currLine][currIndex] = input;
        token = strtok(NULL, ",");
        currIndex++;
      }
      currLine++;
    }
    for(int i = 0; i<9; i++){
      for(int j = 0; j<9; j++){
        printf("%d ", returnMap[i][j]);
      }
      printf("\n");
    }
    printf("\n");
    fclose(mapFile);
    return &returnMap;
}

我得到的输出是

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

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

【问题讨论】:

  • 更好的方法是在main 中声明数组,例如int map[9][9]; 然后将数组传递给函数,例如readMap(argv[1], map)。在这种情况下,所有函数需要做的就是填写值。
  • 等等,我认为将变量声明为静态意味着它直到程序结束才会被销毁。为什么这不适用于这里?我尝试了你的建议,它按照你说的方式工作,但现在我觉得我不理解 static 关键字,我应该
  • @user3386109 好的,那为什么我的第一个方法不能工作呢?我是否错误地引用了从函数返回的指针?
  • 问题在于MAP_ARRAY *map 的行为类似于指向三维数组的指针。声明一个像二维数组一样的指针看起来像int (*map)[9]
  • @DavidC.Rankin 这是不正确的。请不要绕过同行评审系统在 cmets 部分发布答案 - 我们不能对它们投反对票。

标签: c


【解决方案1】:

问题出在这里:

    printf("%d ", *map[i][j]);

它错误地解释了多个取消引用。当i = 1 时,它通过跳过整个数据结构来计算map[i](这不是你想要的)。您需要以下内容:

    printf("%d ", (*map)[i][j]);

详细说明错误代码的作用:让我们以i = 0, j = 3 为例。我使用*pointerpointer[0] 相同的想法。那么:

  • map[i] = map[0] = *map = map 指向的东西。这是整个二维数组。
  • map[i][j] = map[0][3] = *map 中索引为 3 的元素 = 数组中索引为 3 的行
  • *map[i][j] = *map[0][3] = map[0][3][0] = 索引为 3 的行中的第一个元素

另一个例子:i = 4, j = 8。那么:

  • map[i] = map[4] = 无限 3-D 数组中索引为 4 的元素,其元素是 2-D 数组 int[9][9]。这超出了范围,因此它会打印一个随机内存位置。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-01-18
    • 2020-06-01
    • 1970-01-01
    • 2021-06-25
    • 1970-01-01
    • 2021-08-23
    • 1970-01-01
    相关资源
    最近更新 更多