我试图找出最好的方法来保存文件指针的记录,以及每个文件的个人信息,比如文件路径。
我的问题是,有一个包含文件指针数组的文件夹结构和一个保存文件信息的文件结构,如何将这两个概念合并,以便我能够保存一个文件指针数组,并存储每个文件的文件路径?
以下文件夹结构的头文件:
#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用于记录文件信息的文件结构的头文件,如文件路径:
#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发布于 2022-05-28 14:05:38
一般的方法是,如果同时需要这两种结构,那么使用另一种结构,如果您需要使用一个联合(很可能带有标记字段)来判断它持有的结构中的哪一个。在您的示例中,它听起来像是有n个文件的1文件夹,所以您的folder_file_结构将有一个files_数组。如果您有多个文件夹,那么您需要一个folder_file_数组。
FILE *通常意味着打开文件句柄。那真的是你的用例吗?与一堆路径相反,您只能打开文件,因为您必须对其进行操作。另外,为什么FILE **反对FILE *?
发布于 2022-05-28 19:44:11
通常最好让系统管理文件指针。例如,可以在struct之外重新打开该文件。或者刚刚关门。struct可以获得FILE*的副本,但是在创建时无法知道它是否指向同一个文件。
无论如何,有时我们可能需要一种方法来存储一个文件集合的信息。
一个例子
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的指针数组。cap和size是常见的,inc是文件中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*);insert()接受一个File指针是很容易定制的,File.trim()释放useshow()中的所有指针接受一个标题,因为convenienceget_pos()返回提供的文件在arraydestroy()中的位置,返回NULL,以便于在同一行中使指针失效。
用于此测试的main
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份文件(
F 245)
测试输出
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 destroyedstuff.h
#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*);
#endifstuff.c
#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()指针,因为我不喜欢隐式的东西,我喜欢它们作为对未来事物的额外提醒。
https://stackoverflow.com/questions/72416254
复制相似问题