【问题标题】:File to dynamic array in c文件到c中的动态数组
【发布时间】:2017-06-06 08:54:57
【问题描述】:

免责声明:我是 C 新手。

将 .txt 文件(也可以是其他文件类型)中的每一行转换为动态 calloc() 数组的最佳方法是什么,反之亦然?

在我的文件中,我必须遵循:

1 Hello
2 18
3 World
4 15
etc...

我想在数组中有这样的东西:

[0] Hello
[1] 18
[2] World
[3] 15
etc...

我现在的代码:

FILE *file;
file = fopen("test.txt", "r");
int i = 0;

//make dynamic calloc array
//while line!= EOF
    //put line[i] into array
    //i++
    //realloc array, size +1

fclose(file);

这是一种好的方式还是有更好的方式? 如果有人可以帮助我一些代码,我将非常感激。

【问题讨论】:

  • 所以文件的每一行都以一个数字开头。那个号码的目的是什么?只是行号?这些数字必须存储在某个地方吗?

标签: c arrays dynamic realloc calloc


【解决方案1】:

您接近正确的解决方案,但是在这里每次有新行时都会重新分配动态数组,您可以做的是提前在数组中分配 N 字节并每次都重新分配大小,这将避免数组和系统调用的频繁内存移动:

FILE *file;
file = fopen("test.txt", "r");
int i = 0;

int max = 256;
int resize = 512;
char **arr = malloc(max * sizeof(*arr));


//make dynamic calloc array
//while line!= EOF
    //put line[i] into array
    //i++

    if(i == max)
      realloc array, size + reisze;

fclose(file);

【讨论】:

    【解决方案2】:

    我会先获取行数,然后为数组分配内存以避免 realloc() 调用(可能分配一个新的内存块并复制内存区域)。 但我不确定这种方式是否更有效。 这是我的示例代码:

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    static int get_nlines(FILE* fp)
    {
        int nlines = 0;
    
        int ch;
        while (!feof(fp)) {
            ch = fgetc(fp);
            if (ch == '\n') {
                nlines++;
            }
        }
    
        fseek(fp, 0, SEEK_SET);
        return nlines;
    }
    
    static char* get_value(char* s)
    {
        char* pch;
        pch = strtok(s, " ");
        if (pch != NULL) {
            pch = strtok(NULL, " ");
            if (pch != NULL) {
                return strdup(pch); // need to free() after use
            } else {
                return NULL;
            }
        } else {
            return NULL;
        }
    }
    
    int main()
    {
        FILE* fp = fopen("test.txt", "r");
        if (fp != NULL) {
            int nlines = get_nlines(fp);
    
            printf("nlines: %d\n", nlines);
    
            // make values..
            char** values = calloc(nlines + 1, sizeof(char*)); // +1 for a sentinel
            if (values != NULL) {
                char line[1024];
                int idx = 0;
                while (fgets(line, sizeof(line), fp) != NULL) {
                    values[idx] = get_value(line);
                    idx++;
                }
            }
    
            // use values..
            char** p = &values[0];
            while (*p != NULL) {
                printf("%s\n", *p);
                p++;
            }
    
            // clean values..
            p = &values[0];
            while (*p != NULL) {
                free(*p);
                p++;
            }
    
            fclose(fp);
        } else {
            perror("test.txt");
        }
    }
    

    结果:

    $ ./a.out
    nlines: 4
    Hello
    
    18
    
    World
    
    15
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-06-11
      • 1970-01-01
      • 1970-01-01
      • 2020-10-04
      • 2017-04-24
      • 2017-03-11
      • 2010-10-10
      • 2016-05-09
      相关资源
      最近更新 更多