C 如何读取一个大文件(最多2 000个字符)并存储它们

C 如何读取一个大文件(最多2 000个字符)并存储它们,c,overflow,buffer,C,Overflow,Buffer,我试图解决一个问题,因为我有一个包含迷宫的输入文件,我知道如何解决迷宫,但我不知道如何储存迷宫。 我无法将其存储在字符数组中,因为该文件最多可以包含20亿个字符。 我不知道如何在不破坏缓冲区的情况下存储文件。。。 使用read命令读取文件(不允许使用fread)。为什么不为2000000000字符数组分配内存?唯一的限制是你的电脑内存。如果有足够的连续地址空间,就没有问题 您可以尝试类似于char*my_maze=(char*)malloc((20000000000*sizeof(char))您

我试图解决一个问题,因为我有一个包含迷宫的输入文件,我知道如何解决迷宫,但我不知道如何储存迷宫。 我无法将其存储在字符数组中,因为该文件最多可以包含20亿个字符。 我不知道如何在不破坏缓冲区的情况下存储文件。。。
使用read命令读取文件(不允许使用fread)。

为什么不为2000000000字符数组分配内存?唯一的限制是你的电脑内存。如果有足够的连续地址空间,就没有问题


您可以尝试类似于char*my_maze=(char*)malloc((20000000000*sizeof(char))

您可以使用一个链表,其中每个节点都包含一个字符,这将占用大量的空间,但它可以做到这一点。

从您的描述听起来,您需要阅读迷宫,然后存储已解迷宫的副本

让我们假设您的迷宫将存储为一个二维字符数组,其中一个字符表示砖墙-例如“*”,另一个字符表示开放空间-例如“”,因此一个小的8 x 8迷宫可能如下所示:

****** * * * * **** * * * * * *** ** * * * *** **** *** **** ****** * * * * **** * * * * * *** ** * * * *** **** *** **** 然后,您需要进行求解,并使用表示求解路径步骤的字符存储迷宫。假设字符为“+”,它将如下所示:

******+* *++++++* *+ *** * *+ * * *+*** ** *+++* * ***+**** ***+**** ******+* *++++++* *+ *** * *+ * * *+*** ** *+++* * ***+**** ***+**** 是我,我的目标是使用很少的内存,我要做的第一件事是将迷宫转换为位,其中星号用1表示,空格用0表示。生成的地图将小8倍。然后我会进行求解,但就像我不能在映射中存储“+”一样-位只能有2个值-,我会将每个步骤的位置存储在链表上。然后我将通过读取地图的每个位置并在列表中检查它来保存输出迷宫,如果它在那里,我将输出一个“+”,否则我将检查位并输出“*”(如果它为1),如果它为0

就像这是一个大学项目一样,我不会在这里给你所有的代码——你应该自己写——但我会给你足够的线索,告诉你一些未优化的代码的形式

struct pos{
int x,y;
结构位置*下一步;
};
结构位置*步骤列表=空;
#定义迷宫宽度位((迷宫宽度+7)/8)
无符号字符位迷宫[迷宫高度][迷宫宽度位];
int getbit(int x,int y)
{
无符号字符v=bitmaze[y][(x/8)];
v>>=7-(x%8);
返回(v&1);
}
无效保存(文件*fp)
{
int x,y,找到;
结构位置*当前步骤;
对于(y=0;yy==y)
发现=1;
其他的
cur_step=cur_step->prox;
}
如果(找到)
fputc(+',fp);
其他的
fputc(getbit(x,y)“*”:“”,fp);
}
}
}

希望这对你有帮助。
guilleamodeo。

您是否可以使用操作系统的功能(如内存映射文件)直接将文件视为字节数组?你说“不允许”是什么意思?谁不允许?你在找lseek64吗?这是一个学校项目,我们只允许非常有限的程序:打开、关闭、写入、读取、malloc和免费。但是,我们可以编码任何我们想要的函数……要考虑的问题是:你能用更少的记忆来代表迷宫,而不是它的“图像”作为一个字符数组吗?例如,通过将其转换为边和顶点的抽象图(如果您已经研究过的话)?如果不是,你能在迷宫中导航而不同时读取整个内容吗,比如在文件中来回移动,在不同的时间查看迷宫的不同部分?(这通常应该通过
fseeko
ftello
功能来完成,您不允许提及这些功能。)@EricPostpischil:阅读作业,我认为OP是针对您的第二个建议。“如何处理巨大的文件”是一个很好的练习,而试图把所有的文件都塞进内存并不总是一个选择。它将只使用一个“行”内存(可以安全地说这些是行吗?),我不相信你可以用更少的内存。我听说分配这么大的内存是一件非常糟糕的事情,有很高的溢出风险?不是吗there@istovatis当然你想要“…=(char*)malloc((2000000000…。(添加
*
)。进一步推荐
char*my\u maze=malloc(2000000000*sizeof(*my\u maze))
“PC内存”不是“唯一的限制”。限制可能更高(由操作系统作为虚拟内存提供)或更低(如果受到操作系统、C实现或系统管理员设置的资源限制的限制)。@zopa:如果你充分利用了大量内存,并且没有干扰系统的其他重要用途(如其他用户试图完成工作),那么分配大量内存是不错的。存在“溢出”的风险您的程序与缓冲区大小无关;它是通过编写正确的代码来确定的。或者,如果您的意思是内存不足而无法获得所请求的数量,那么这将由您来确定。
malloc
如果无法提供内存,将返回零。在这种情况下,您必须找到另一种解决方案。使用2Gb时,它不会返回零不管你怎么做,它总是会消耗很多内存,很多。但是为什么不直接使用字符数组呢?我认为你应该使用一些不连续的东西。虽然链表可以避免单个大的分配,但它也会使用更多的总内存,而且处理起来非常慢……哇,好主意!我只有一个挫折,我知道有一条路可以进去,也可能有几条路可以出去,但也许我可以为计算设置一个空位,然后把它放回原来的位置
struct pos {
    int x,y;
    struct pos *next;
};

struct pos *step_list=NULL;

#define MAZE_WIDTH_BITS  ((MAZE_WIDTH + 7) / 8)

unsigned char bitmaze[MAZE_HEIGHT][MAZE_WIDTH_BITS];

int getbit(int x,int y)
{
    unsigned char v = bitmaze[y][(x / 8)];


    v >>= 7 - (x % 8);
    return (v & 1);
}


void save_maze(FILE *fp)
{
    int x,y,found;
    struct pos *cur_step;

    for(y=0;y<MAZE_HEIGHT;y++)
    {
        for(x=0;x<MAZE_WIDTH;x++)
        {
            found=0;
            cur_step=step_list;
            while(cur_step && !found)
            {
                if(cur_step->x==x && cur_step->y==y)
                     found=1;
                else
                    cur_step=cur_step->prox;
            }
            if(found)
                fputc('+',fp);
            else
                fputc( getbit(x,y) ? '*' : ' ',fp);
        }
    }
}