【问题标题】:C Dynamic Memory Allocation - Read Data from FileC 动态内存分配 - 从文件中读取数据
【发布时间】:2012-04-18 10:11:31
【问题描述】:

我正在从 MATLAB 复制 load() 函数以用于 C 应用程序。我无法动态加载数据和初始化我需要的数组。更具体地说,我正在尝试将 fgets 与已使用 calloc 初始化的数组一起使用,但我无法使其正常工作。该功能如下,感谢您的帮助。

编辑:更新的代码低于以下有缺陷的示例。

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

void *load(const char *Filename);

void *load(const char *Filename)
{
    FILE* FID;
    if ((FID = fopen(Filename, "r")) == NULL)
    {
        printf("File Unavailable.\n");
    }
    else
    {
        int widthCount = 0, heightCount = 0;

        char ReadVal;
        while ((ReadVal = fgetc(FID)) != '\n')
        {
            if (ReadVal == ' ' || ReadVal == ',' || ReadVal == '\t')
            {
                widthCount++;
            }
        }

        rewind(FID);
        char* String = calloc(widthCount * 100, sizeof(char));
        while (fgets(*String, widthCount+1, FID) != EOF)
        {
            heightCount++;
        }
        double* Array = calloc(widthCount * heightCount, sizeof(double));
        rewind(FID);
        int i = 0, j = 0;
        char * pch;
        while (fgets(*String, widthCount+1, FID) != EOF)
        {
            pch = strtok(String, " ,\t");
            while (pch != NULL)
            {
                Array[i][j] = strtod(pch, NULL);
                pch = strtok (NULL, " ,\t");
                j++;
            }
            i++;
            j = 0;
        }

        fclose(FID);
        return Array;

    }

}

修改后的代码: 此解决方案适用于任何遇到类似问题的人。

void *load(const char *Filename)
{
    FILE* FID;
    if ((FID = fopen(Filename, "r")) == NULL)
    {
        printf("File Unavailable.\n");
        return NULL;
    }
    else
    {   
        int widthCount = 0, heightCount = 0;
        double *Array;
        char Temp[100];
        while ((Temp[0] = fgetc(FID)) != '\n')
        {
            if (Temp[0] == '\t' || Temp[0] == ' ' || Temp[0] == ',')
            {
                widthCount++;
            }
        }
        widthCount++;
        //printf("There are %i columns\n", widthCount);
        rewind(FID);
        while (fgets(Temp, 99, FID) != NULL)
        {
            heightCount++;
        }
        //printf("There are %i rows\n", heightCount);
        Array = (double *)calloc((widthCount * heightCount), sizeof(double));
        rewind(FID);
        int i = 0;
        while (!feof(FID))
        {

            fscanf(FID, "%lf", &*(Array + i));
            fgetc(FID);
            i++;
        }

        return Array;   
    }
}

【问题讨论】:

    标签: c dynamic-memory-allocation fgets calloc


    【解决方案1】:

    数组不是二维数组而不是Array[i][j] = strtod(pch, NULL); 只是增加指针*(Array++) = strtod(pch, NULL);

    【讨论】:

    • 谢谢,我没听懂。我的主要问题是通过 fgets 命令。我需要能够根据我在运行时确定的行大小来获取每一行。
    • @NathanTornquist 它可能有助于提供文件格式的示例,如何设置线宽等
    • 我没有线宽。对于类,目标是让用户提供要加载的数据的维度。我决定尝试在没有任何这些值的情况下加载所有数据。这就是函数开头计算宽度和高度的目的。
    • “我的主要问题是无法通过 fgets 命令。” 您已经注意到 fgets 在一般情况下完全不适合这项工作。好的。如果您在阅读之前不知道任何特定行的长度,您需要getline 或类似的东西。截至 2008 年,getline 是 POSIX 的一部分,因此它应该可以在任何 unixish 系统上使用。
    • @NathanTornquist 字节数只是一个提示,或者已经分配的大小,getline 会自动重新分配数组以适应数据。如果您有 getlien,您可以在读取值时节省大量增加数组和移动数据的工作。另一种方法是一次将每个新值读取一个字符到一些小的固定缓冲区(例如,以适应 8 或 10 个小数位),然后将每个新值转换为 Array
    猜你喜欢
    • 1970-01-01
    • 2021-06-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多