C 如何确定一个文件(所有内容)的大小,以便一次为其分配内存?
我正在尝试为包含单词(以:\n分隔)的文件内容分配内存 如何替换16000以使其可用于更大的文件 我的代码:C 如何确定一个文件(所有内容)的大小,以便一次为其分配内存?,c,file,size,calloc,C,File,Size,Calloc,我正在尝试为包含单词(以:\n分隔)的文件内容分配内存 如何替换16000以使其可用于更大的文件 我的代码: typedef struct node { bool is_word; struct node* children[27]; } node; node* root; bool load(const char* dictionary) { FILE *fp; fp = fopen(dictionary, "rb"); node* node_
typedef struct node {
bool is_word;
struct node* children[27];
} node;
node* root;
bool load(const char* dictionary)
{
FILE *fp;
fp = fopen(dictionary, "rb");
node* node_bucket = calloc(16000, sizeof(node));
node* next_free_node = node_bucket;
// compute...
// to later free the memory with another function
root = node_bucket;
}
谢谢您可以在不知道文件大小的情况下动态分配内存。我使用的块大小是2的幂,这通常对块I/O更友好。当最后一个块仅部分使用时,它会浪费一点,但下面是一个示例,您可以调整它以使用节点结构:
#include <stdio.h>
#include <stdlib.h>
#define BLOCKSIZE 16384
int main(void) {
unsigned char *buf = NULL;
unsigned char *tmp = NULL;
size_t totalread = 0;
size_t currentsize = 0;
size_t currentread = 0;
FILE *fp;
if((fp = fopen("test.txt", "rb")) == NULL)
exit(1);
do {
currentsize += BLOCKSIZE;
if((tmp = realloc(buf, currentsize)) == NULL)
exit(1);
buf = tmp;
currentread = fread( &buf[totalread], 1, BLOCKSIZE, fp);
totalread += currentread;
} while (currentread == BLOCKSIZE);
printf("Total size was %zu\n", totalread);
free(buf);
fclose(fp);
return 0;
}
#包括
#包括
#定义块大小16384
内部主(空){
无符号字符*buf=NULL;
无符号字符*tmp=NULL;
大小\u t totalread=0;
大小\u t currentsize=0;
大小\u t currentread=0;
文件*fp;
if((fp=fopen(“test.txt”、“rb”))==NULL)
出口(1);
做{
currentsize+=块大小;
if((tmp=realloc(buf,currentsize))==NULL)
出口(1);
buf=tmp;
currentread=fread(&buf[totalread],1,块大小,fp);
totalread+=当前读取;
}而(currentread==块大小);
printf(“总大小为%zu\n”,totalread);
免费(buf);
fclose(fp);
返回0;
}
获取文件大小的最简单方法是使用:
然而,正如评论所说,这是不可移植的,因为N1570在“7.21.9.2 seek函数”中提供了文档:
2。。。。。。二进制流不需要有意义地支持带有
SEEK\u END的值从何而来
或者,您可以编写一个函数,自己获取文件大小:
size_t fSize(FILE *fp)
{
void *ptr = malloc(1);
size_t size = 0;
while(fread(ptr, 1, 1, fp) == 1)
size++;
if(feof(fp))
return size;
else
return 0; // reading error
}
准确度-效率权衡:
size_t fRoughSize(FILE *fp)
{
void *ptr = malloc(1024);
size_t size = 0;
while(fread(ptr, 1024, 1, fp) == 1024)
size += 1024;
if(feof(fp))
return size;
else
return 0; // reading error
}
我认为最便携的方式是使用。这将要求您首先在文件中查找,然后再查找到底,这可能不是最佳性能。在POSIX上,您可以使用
fstat()
来询问文件系统。@user3419211是否希望文件中存储的确切字节数不包括字符“\n”。包括“\n”!我使用了ftell(),正如建议的那样,它似乎很有效。为什么不使用动态方法,在需要时分配一个子项呢?您可以使用if(fp==NULL)
检查它是否有效,然后使用if(node\u bucket==NULL)
。始终检查文件打开和malloc
系列的返回值。您可能认为它应该一直工作,但这可能是您第一次警告内存泄漏,或者您要求的内存超出可用内存。
size_t fRoughSize(FILE *fp)
{
void *ptr = malloc(1024);
size_t size = 0;
while(fread(ptr, 1024, 1, fp) == 1024)
size += 1024;
if(feof(fp))
return size;
else
return 0; // reading error
}