C语言 fgets + dynamic malloc/realloc with a .txt as stdin



我正在尝试读取文件的行.txt,但不知道每行的大小...首先我使用了 getline 指令(并且工作正常),但我的老师不允许我使用该指令,他说我只能将 fgets 语句与 malloc 和 realloc 一起使用......

这是一个输入示例,具有可变的行大小:

[9.3,1.2,87.9]
[1.0,1.0]
[0.0,0.0,1.0]

如图所示,每行定义一个没有大小限制的不同向量

有人可以帮助我实现这种方法吗?

谢谢。

注意:我忘了提到,要编译程序,我使用以下命令:

g++ -Wall-Wextra-Werror-pedantic main.c-o metbasicos.c metintermedios.c eda.exe
./eda.exe <eda.txt

我会说做类似的事情

    while(fgets(buf, LEN, stdin)){
            z = strtok(buf, ",");
            *(*(matrix + i)) = atof(z);
            for(j = 1; j < col; ++j){
                    z = strtok(NULL, ",");
                    *(*(matrix + i) + j) = atof(z);
            }
            ++i;
    }

您唯一需要注意的额外事情是确保从第一个和最后一个元素上去除括号。

当然,如果您不知道最终数组的大小,则可能需要这样的东西:

    struct data_t {
            int nval;               /* current number of values in array */
            int max;                /* allocated number of vlaues */
            char **words;           /* the data array */
    };
    enum {INIT = 1, GROW = 2};
    ...
    while (fgets(buf, LEN, stdin)) {
            if (data->words == NULL)
                    data->words = malloc(sizeof(char *));
            else if (data->nval > data->max) {
                    data->words = realloc(data->words, GROW * data->max *sizeof(char *));
                    data->max = GROW * data->max;
            }
            z = strtok(buf, "n");
            *(data->words + i) = malloc(sizeof(char) * (strlen(z) + 1));
            strcpy(*(data->words + i), z);
            i++;
            data->nval++;           
    }
    data->nval--;

如果将这两个 while 循环组合成一个循环,则应该已全部设置好。第一个以浮点数读取,第二个适合动态分配空间。

如果可以使用多个步骤,则使用一个函数来获取 malloc 内存所需的信息。 (例如确定行数和最长行) 此功能将为您执行此操作(给定文件名和位置)

[编辑] LineCount - 此函数将为您提供行数最长行数,以便您可以动态分配内存char **strings;以读取输入文件的行数

int lineCount(char *file, int *nLines)
{
    FILE *fp;
    int cnt=0, longest=0, numLines=0;
    char c;
    fp = fopen(file, "r");
    while ( (c = fgetc ( fp) ) != EOF )
    {
        if ( c != 'n' ) 
        {
            cnt++;    
            if (cnt > longest) longest = cnt;
        }
        else 
        {
            numLines++;
            cnt= 0;
        }
    }
    *nLines = numLines+1;//add one more
    fclose(fp);
    return longest+1;
}

这是读取您提供的输入文件的实现,使用上面的函数获取输入文件的未知尺寸......

#include <ansi_c.h>
#include <stdio.h>
#define FILENAME "c:\dev\play\in.txt" //put your own path here
#define DELIM "- ,:;//_*&[]n"  //change this line as needed for search criteria
int lineCount(char *file, int *cnt);
void allocMemory(int numStrings, int max);
void freeMemory(int numStrings);
char **strings;
int main()
{
    int numLines, longest, cnt, i;
    FILE *fp;
    longest = lineCount(FILENAME, &numLines);
    char wordKeep[longest];
    allocMemory(numLines, longest);
    //read file into string arrays 
    fp = fopen(FILENAME, "r");
    cnt=0;
    i=0;
    for(i=0;i<numLines;i++)
    {
        fgets(strings[i], longest, fp); 
    }
    fclose(fp);
    freeMemory(numLines);
    getchar();
    return 0;
}
int lineCount(char *file, int *nLines)
{
    FILE *fp;
    int cnt=0, longest=0, numLines=0;
    char c;
    fp = fopen(file, "r");
    while ( (c = fgetc ( fp) ) != EOF )
    {
        if ( c != 'n' ) 
        {
            cnt++;    
            if (cnt > longest) longest = cnt;
        }
        else 
        {
            numLines++;
            cnt= 0;
        }
    }
    *nLines = numLines+1;//add one more
    fclose(fp);
    return longest+1;
}
void allocMemory(int numStrings, int max)
{
    int i;
    // need number of lines by longest line for string containers
    strings = calloc(sizeof(char*)*(numStrings+1), sizeof(char*));
    for(i=0;i<numStrings; i++)
    {
      strings[i] = calloc(sizeof(char)*max + 1, sizeof(char));
    }
}
void freeMemory(int numStrings)
{
    int i;
    for(i=0;i<numStrings; i++)
        if(strings[i]) free(strings[i]);
    free(strings);  
}

最新更新