C 如何确定一个文件(所有内容)的大小,以便一次为其分配内存?

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_

我正在尝试为包含单词(以:\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_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
}