繁体   English   中英

fgets不阅读EOL吗?

[英]fgets not reading EOL?

因此,基本上我正在用C编写基于文本的rpg,我想创建一个地图系统。 基本上,我遇到麻烦的功能是从一个看起来像这样的文件中读取“文本映射”:

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

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

这是我遇到问题的功能:

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

我可以再换一双眼睛吗?

分析

w的值是多少? 对于显示的数据,也必须至少为12才能获得换行符(10个字符,换行符和null)。 稍后您将遇到问题,因为您不能(安全地)返回本地数组map_return ,但这是一个单独的错误。 另外,您应该在map_return[a][b] = fgets(c, w, fp);上收到类型不匹配警告map_return[a][b] = fgets(c, w, fp); 这行是因为map_return[a][b]是一个charfgets()返回一个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...

该功能的错误报告最少; 您可以根据自己的需要进行改进。

与其指责fgets ,不如看看您的逻辑。 您在内部循环中循环w次,每次读取w个字节……总计h*w*w个字节。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM