C - 读取文件并将文本放入具有动态内存分配的字符指针

Posted

技术标签:

【中文标题】C - 读取文件并将文本放入具有动态内存分配的字符指针【英文标题】:C - Reading file and putting text into char pointer with dynamic memory allocation 【发布时间】:2020-07-28 13:43:34 【问题描述】:

我正在尝试从我为 C 程序编写的外部文件中逐行读取基本着色器。在文件中有两个着色器:顶点和片段。我创建了这个函数来逐行读取它,并确定它正在读取哪个着色器并返回结构ParsedShader

typedef struct 
char* vertex;
char* fragment;
 ParsedShader;

static ParsedShader ParseShader(char *filepath) 

    char* vert;
    char* frag;
    vert = "\n";
    frag = "\n";

    char line[128];

    enum ShaderType 
        NONE = -1,
        VERTEX = 0,
        FRAGMENT = 1
    ;

    enum ShaderType type = NONE;

    FILE* file;
    fopen_s(&file, filepath, "r");

    while (fgets(line, sizeof(line), file)) 
        if (strstr(line, "#shader")) 

            if (strstr(line, "vertex")) type = VERTEX;

            else if (strstr(line, "fragment")) type = FRAGMENT;
        
        
        else 

            if (type == VERTEX) 
            //Put Lines into vert char *
            //Here is where I don't know what to do
            
            else if (type == FRAGMENT) 
            //Put Lines into frag char *
            //Here I don't know what to do either
            

        
    

    fclose(file);

    ParsedShader result;
    result.vertex = vert;
    result.fragment = vert;

    return result;

问题是由于内存的原因,我无法将文本放入 vertfrag 变量中。我知道它必须使用mallocrealloc 函数来完成,但就是无法让它工作。我已经创建了一个释放内存的函数:

static DeleteShader(ParsedShader* shader) 
    if (shader) 
        free(shader->vertex);
        free(shader->fragment);
    

【问题讨论】:

char* vert = malloc( MAX_VERT_SIZE_IN_BYTES );,frag 也是如此。然后strcpy(vert, WHATEVER_YOU_NEED_TO_PUT_THERE); 复制您需要放置在那里的数据(无论如何,它必须是一个以 NULL 结尾的字符串)。每当您检测到 MAX_VERT_SIZE_IN_BYTES 不够时,请使用 realloc @RobertoCaboni 不要忘记初始化缓冲区的内容。 @MikeCAT 当然,如果您需要在将某些内容复制到缓冲区之前读取缓冲区:vert[0] = 0。否则它并不重要,因为 strcpy 不会关心以前的内容。 @RobertoCaboni 啊,我误会你用的是strcat() 【参考方案1】:

初始化:

vert = calloc(1, sizeof(char));

这将分配一个元素并将其初始化为零(字符串结尾)。

添加字符串:

vert = realloc(vert, strlen(vert) + strlen(line) + 1);
strcat(vert, line);

这将重新分配缓冲区以具有连接的字符串(包括字符串结束标记),然后连接字符串。

你可以为frag做同样的事情。

此代码无效,因为它会多次扫描字符串以测量其长度,但它应该适用于大小高达几 KB 的文件。

callocrealloc 添加错误检查将使代码更安全。

【讨论】:

【参考方案2】:

*vert 变量设置为null,并使用与某种计数器集成的realloc 函数。

int vertCount = 0;

然后每次你想添加 char 时都做这样的事情:

vert = (char*)realloc(vert,sizeof(char)*(vertCount+1));
vert[vertCount++] =  char

注意:通常不建议使用 realloc,因为它会导致内存泄漏。 更好的想法是有一些int maxCount;int current;

您将 maxCount 的值硬编码为 10 ,并使用 malloc 函数,然后只有在当前达到 maxCount 后,您才会增加 maxCount 并执行例如 realloc,然后您将有更多机会创建过载。

编辑: 我以为你会一个字一个字。与 realloc 相同的逻辑可以只应用 realloc 和 strlen(string) + 1 (原因是 '\0' char),然后使用 strcat 复制整行。 但是将您的变量设置为空字符串(“”),这样您就不必第一次使用 strcpy。

【讨论】:

注:c - Do I cast the result of malloc? - Stack Overflow

以上是关于C - 读取文件并将文本放入具有动态内存分配的字符指针的主要内容,如果未能解决你的问题,请参考以下文章

动态读取文本文件并放入 C 中的指针字符数组

指针数组的动态内存分配

指向动态二维字符数组的三重指针的内存分配

C 编程 - realloc 应该多久使用一次?

如何读取文本文件键值并将值分配给字符串 var?

如何在C中为char**动态分配内存