首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >文件I/O结构

文件I/O结构
EN

Stack Overflow用户
提问于 2022-05-28 13:58:34
回答 2查看 111关注 0票数 -1

我试图找出最好的方法来保存文件指针的记录,以及每个文件的个人信息,比如文件路径。

我的问题是,有一个包含文件指针数组的文件夹结构和一个保存文件信息的文件结构,如何将这两个概念合并,以便我能够保存一个文件指针数组,并存储每个文件的文件路径?

以下文件夹结构的头文件:

代码语言:javascript
运行
复制
#ifndef FOLDER_STRUCT_H
#define FOLDER_STRUCT_H

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

struct folder_
{
    FILE **files;
    size_t current_size;
    size_t capacity;
};

typedef struct folder_ folder_t;

folder_t *folder_create(size_t initial_size); //-----------------------Create a folder struct

void folder_destroy(folder_t *folder); //------------------------------Destroy a folder struct

bool folder_insert_file(folder_t *const folder, FILE *const file); //--Insert a file

FILE *folder_get_file(folder_t *const folder, size_t index); //--------Get a file by index

FILE **folder_get_file_list(folder_t *const folder); //----------------Get a list of files

int folder_get_size(folder_t *folder); //------------------------------Get folder size

int folder_get_total_capacity(folder_t *folder); //--------------------Get folder capacity

#endif

用于记录文件信息的文件结构的头文件,如文件路径:

代码语言:javascript
运行
复制
#ifndef FILE_H
#define FILE_H

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

struct file_
{
    FILE *file;
    char *file_path;
};

typedef struct file_ file_t;

#endif
EN

回答 2

Stack Overflow用户

发布于 2022-05-28 14:05:38

一般的方法是,如果同时需要这两种结构,那么使用另一种结构,如果您需要使用一个联合(很可能带有标记字段)来判断它持有的结构中的哪一个。在您的示例中,它听起来像是有n个文件的1文件夹,所以您的folder_file_结构将有一个files_数组。如果您有多个文件夹,那么您需要一个folder_file_数组。

FILE *通常意味着打开文件句柄。那真的是你的用例吗?与一堆路径相反,您只能打开文件,因为您必须对其进行操作。另外,为什么FILE **反对FILE *

票数 0
EN

Stack Overflow用户

发布于 2022-05-28 19:44:11

通常最好让系统管理文件指针。例如,可以在struct之外重新打开该文件。或者刚刚关门。struct可以获得FILE*的副本,但是在创建时无法知道它是否指向同一个文件。

无论如何,有时我们可能需要一种方法来存储一个文件集合的信息。

一个例子

代码语言:javascript
运行
复制
typedef struct
{
    char* name;
    FILE* F;

}   File;

typedef struct
{
    size_t size;
    size_t cap;   // capacity
    size_t inc;   // increment
    File** info;  // data array

}   Folder;

File中,我们可以存储大小、日期,或者权限。

Folder是指向File的指针数组。capsize是常见的,inc是文件中Folder的增量大小。

执行了以下几项职能:

代码语言:javascript
运行
复制
Folder* create(size_t capacity, size_t step);
Folder* destroy(Folder*);
int     insert(File*, Folder*);
int     show(Folder*, const char*);
int     trim(Folder*);

int     get_pos(const char* f_name, Folder*);

  • insert()接受一个File指针是很容易定制的,File.
  • trim()释放use
  • show()中的所有指针接受一个标题,因为convenience
  • get_pos()返回提供的文件在array
  • destroy()中的位置,返回NULL,以便于在同一行

中使指针失效。

用于此测试的main

代码语言:javascript
运行
复制
int main(void)
{
    const char tst_size = 10;
    const char* scan[] = {"File_7533.tst", "File_7500.tst"};
    srand(220520);

    Folder* tst = create(4, 4);
    show(tst, "just created");

    char f_name[20] = {0};
    for (int i = 0; i < tst_size; i += 1)
    {
        sprintf(f_name, "File_%04d.tst", 1+rand()%10000);
        insert_this(f_name,NULL,tst);
    }
    sprintf(f_name, "%d files inserted", tst_size);
    show(tst, f_name);
    trim(tst);
    show(tst, "after trim()");
    for (int i = 0; i < sizeof(scan) / sizeof(scan[0]);i+=1)
        printf( "search por \"%s\" returned %d\n", scan[i],
            get_pos(scan[i], tst));
    tst = destroy(tst);
    return 0;
}

创建一个大小为4的文件夹,并将其分组为4组,插入10份文件(

  • ),
  • ,内容为2文件(
  • ),内容被销毁(

F 245)

测试输出

代码语言:javascript
运行
复制
just created
[0/4 files (step = 4)]

insert() size extended to 8
insert() size extended to 12
10 files inserted
[10/12 files (step = 4)]
  0  File_2037.tst
  1  File_5785.tst
  2  File_6602.tst
  3  File_7231.tst
  4  File_0854.tst
  5  File_7102.tst
  6  File_7533.tst
  7  File_6460.tst
  8  File_1717.tst
  9  File_1948.tst

trim() new size: 10
after trim()
[10/10 files (step = 4)]
  0  File_2037.tst
  1  File_5785.tst
  2  File_6602.tst
  3  File_7231.tst
  4  File_0854.tst
  5  File_7102.tst
  6  File_7533.tst
  7  File_6460.tst
  8  File_1717.tst
  9  File_1948.tst

search for "File_7533.tst" returned 6
search for "File_7500.tst" returned -1
Folder structure destroyed

stuff.h

代码语言:javascript
运行
复制
#ifndef STUFF_H
#define STUFF_H

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct
{
    char* name;
    FILE* F;

}   File;

typedef struct
{
    size_t size;
    size_t cap;   // capacity
    size_t inc;   // increment
    File** info;  // data array

}   Folder;

Folder* create(size_t capacity, size_t step);
Folder* destroy(Folder*);
int     insert(File*, Folder*);
int     show(Folder*, const char*);
int     trim(Folder*);

int     get_pos(const char* f_name, Folder*);

#endif

stuff.c

代码语言:javascript
运行
复制
#include "stuff.h"

Folder* create(size_t capacity, size_t step)
{
    Folder* nw = (Folder*)malloc(sizeof(Folder));
    if (nw == NULL) return NULL;
    nw->size = 0;
    nw->cap  = capacity;
    nw->inc = step;
    nw->info = (File**) malloc(nw->cap*sizeof(File*));
    for (int i = 0; i < nw->cap; i += 1)
        nw->info[i] = NULL;
    return nw;
}

Folder* destroy(Folder* f)
{
    if (f == NULL) return NULL;
    for (int i = 0; i < f->size; i += 1)
    {
        free(f->info[i]->name);
        free(f->info[i]);
    }
    free(f->info);
    free(f);
    printf("Folder structure destroyed\n");
    return NULL;
}

int insert(File* item, Folder* f)
{
    if (f == NULL) return -1;
    if (item == NULL) return -2;
    if (f->size >= f->cap)
    { // extends folder struct size
        size_t  new_size = f->cap + f->inc;
        File* p = realloc((void*)f->info, new_size*sizeof(File*));
        if (p == NULL) return -3; // error extending
        f->info = (File**) p;
        f->cap = new_size;
        printf("insert() size extended to %zd\n", f->cap);
    };
    // ok, new File then
    File* nw   = (File*)malloc(sizeof(File));
    nw->name = (char*)malloc(1 + strlen(item->name));
    strcpy(nw->name, item->name);
    nw->F = item->F;
    f->info[f->size]      = nw;
    f->size += 1;
    return (int)f->size;        
}

int show(Folder* f, const char* msg)
{ 
    if (msg != NULL) printf("%s\n", msg);
    printf(
        "[%zd/%zd files (step = %zd)\n", f->size, f->cap,
        f->inc);
    for (int i = 0; i < f->size; i += 1)
    {
        printf("%3d  %s\n", i, f->info[i]->name);
    }
    printf("\n");
    return 0;
}

int trim(Folder* f)
{
    if (f == NULL) return -1;
    if (f->cap == f->size) return 0; // nothing to do
    File*  p = realloc((void*)f->info, f->size * sizeof(File*));
    if (p == NULL) return -3;  // error extending
    f->info = (File**) p;
    f->cap  = f->size;
    printf("trim() new size: %zd\n", f->cap);
    return 0;
};


int get_pos(const char* f_name, Folder* f)
{
    if (f_name == NULL) return -1;
    for (int i = 0; i < f->size; i += 1)
        if (strcmp(f_name, f->info[i]->name) == 0) return i;
    return -1;
}

注意:我确实转换了所有的malloc()指针,因为我不喜欢隐式的东西,我喜欢它们作为对未来事物的额外提醒。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72416254

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档