1

所以基本上我正在用 C 语言编写一个基于文本的 rpg,我想创建一个地图系统。基本上,我遇到问题的功能是从如下所示的文件中读取“文本映射”:

----------\n
|c  x    [\n
|   x    |\n
]        |\n
----------\0

它基本上是使用二维数组构建的。*编辑我添加了地图在实际数组中的样子。是不是因为我不喜欢终止每一行

这是我遇到问题的功能:

char** readMap(char* map_to_read,int h, int w){
    FILE* fp;
    int a = 0, b = 0;
    char map_return[h][w];
    char* c;

    fp = fopen(map_to_read, "r");

    for(a = 0; a < h; a++){
        for(b = 0; b < w; b++){
            c = (char*)malloc(sizeof(char) * w);
            map_return[a][b] = fgets(c, w, fp);
            printf("%s", c);
        }
        free(c);
    }

    fclose(fp);
    return map_return;
}

一切都读到最后,因为 fgets() 没有读取 EOL。这是 printf 从内部看的样子:http: //i.imgur.com/KojbjDm.png

我可以为此获得第二双眼睛吗?

4

2 回答 2

0

分析

有什么价值w?对于您显示的数据,获取换行符也应该至少为 12(10 个字符,换行符和空值)。稍后您将遇到问题,因为您不能(安全地)返回本地数组map_return,但这是一个单独的错误。此外,您应该map_return[a][b] = fgets(c, w, fp);在线上收到类型不匹配警告,因为map_return[a][b]is acharfgets()返回 a char *free(c)如果您要保存指向它的指针,您将负担不起。这里有很多问题...

你回复:

基本上它是array[h][w], 所以w表示数组的一行中的元素数。

得到了进一步的回应:

所以你需要两个独立的内存块。一个用于读取该行并对其进行验证。可以很简单char line[128];。然后你使用if (fgets(line, sizeof(line), fp) == 0) { ...process EOF/error...}. 假设通过,您验证该行,当它通过验证时,您可以安排将最多w字符从该行复制到map_return数组中。您必须决定是否使用字符串(以 '\0' 结尾)。你可以为任何一个提出理由。然后,您必须处理“不返回局部变量”的问题。

合成

我建议您将接口更改为函数,以便调用者为其分配内存。

此代码编译(但尚未运行)。它不会对读取的行进行太多验证;你可以决定要做什么。

#include <stdio.h>
#include <stdbool.h>

extern bool readMap(char* map_to_read, int h, int w, char map[h][w]);

bool readMap(char* map_to_read, int h, int w, char map[h][w])
{
    FILE* fp;

    if ((fp = fopen(map_to_read, "r")) == 0)
        return false;

    for (int a = 0; a < h; a++)
    {
        char line[128];
        if (fgets(line, sizeof(line), fp) == 0)
        {
            fclose(fp);
            return false;
        }
        for (int b = 0; b < w; b++)
        {
            // Validation
            if (line[b] == '\n' || line[b] == '\0')
            {
                fclose(fp);
                return false;
            }
            map[a][b] = line[b];
            printf("%c", line[b]);
        }
        putchar('\n');
    }

    fclose(fp);
    return true;
}

此代码假定您没有在map数组中存储以 null 结尾的字符串。

示例调用:

int h = 5;
int w = 10;
char map[h][w];

if (mapRead("somefile", h, w, map))
    ...process initialized map...
else
    ...report failure...

该函数的错误报告很少;你可以尽可能多地改进它。

于 2013-04-01T05:09:30.400 回答
0

与其责备,不如fgets看看你的逻辑。您在内部循环中循环时间,每次w读取字节......这是总字节数。wh*w*w

于 2013-04-01T05:23:07.760 回答