【问题标题】:Creating an array of array of structures创建结构数组的数组
【发布时间】:2016-10-20 05:21:52
【问题描述】:

目标

创建结构数组的数组,维度基于文件。然后将其存储到链接列表中。

我正在读取格式如下的文件:

读取格式如下的文件:

name (string)  country (string)  age (int)
john           USA               54
Sam            Aus               18
ect

我不知道文件会有多少行和列,也不知道每列是什么变量类型

所以理论上结构的第一个数组将包含 [NUMBER OF COLUMNS] 结构,这些结构将沿行存储每个变量(使用 void 指针和类型转换)(所以 strucArrayCol[0] = john , structArrayCol[1] = USA等)。

这些结构数组中的每一个都将存储到另一个结构数组中,该数组将具有 [NUMBER OF ROWS] 元素,因此 strucArray2Row[0] = strucArrayCol(包含 john 、 USA 和 54)和 strucArrayRow[1] 将包含另一个strucArrayCol 其中包含 (sam Aus 18)。

所以现在我可以读取文件,找到行数、列以及每列的变量类型。

这是我开始遇到麻烦的地方,因为我不知道该怎么做

1. How to create this array within array ( I know i need to use Malloc)
2.How I would store the variables in the first array of struc, if I
  wanted to store age could I just do

    void *data = malloc(sizeof(int));
    *((int*)data) = TEMP_AGE;

void 数据是 StrucArrayCol 中的结构(在本例中,如果我想存储 John 的年龄 void* 数据将在 StrucArrayCol[3] 中,它位于 StucArrayRow[0] 中,因为它是第 3 列第一行)

对不起,如果这有意义 谢谢

【问题讨论】:

  • 如果你不知道结构体的原型(总是有名字、国家、年龄),那么根本不需要使用结构体。您可以只对每一列进行一维数组,因为它们具有相同的类型。然后创建一个包含每个数组地址的新数组。
  • 对不起,我不擅长解释,问题是我不知道每一列会是什么,而且我必须把它放在“通用链接列表”中,所以我认为这是最好的方法处理未知类型的变量
  • 是的,但是当您可以解析每个列的数据类型时,为什么要使用结构,您可以使用这种数据类型的数组。如果所有列表中都有相同的变量(可能顺序不同,但名称/类型不变),则结构将很有用,然后您可以使用结构并用列表的解析值填充它到下一个数组中的结构和列表中的下一行,然后再做一次。
  • 所以问题是你事先知道结构成员的类型吗?假设它总是有两个字符串和一个 int 还是每次都会改变?
  • 为什么要使用结构体?只有当您知道应该将哪些成员放入该结构时,该结构才会起作用。您不需要仅用于字符串的结构。

标签: c arrays pointers


【解决方案1】:

你可以在一个链表中创建一个链表,假设对任何不是链表的东西都有反感!声明两个链表节点结构,一个用于文件中的行,一个用于每行中的列:

struct column
{
    char *buf;
    struct column *next;
};

struct row
{
    struct column *head;
    struct row *next;
};

一次读取一行文件,每行添加一个row节点。每行都有自己的链接列表,它会将行解析为列。

struct column* column_create(struct column* cursor, char *line)
{
    struct column *node = malloc(sizeof(struct column));
    node->next = 0;
    node->buf = malloc(strlen(line) + 1);
    strcpy(node->buf, line);
    if (cursor)
        cursor->next = node;
    return node;
}

struct row* row_create(struct row* cursor, char *line)
{
    struct row *node = malloc(sizeof(struct row));
    node->next = 0;
    node->head = 0;

    //parse the line in to columns
    struct column *col = 0;
    char *token = strtok(line, " \n");
    while (token)
    {
        col = column_create(col, token);
        if (!node->head)
            node->head = col;
        token = strtok(NULL, " \n");
    }

    if (cursor)
        cursor->next = node;
    return node;
}

或者您可以使用 2 维文本数组(这将是 3 维字符数组)来执行此操作。或者使用一个字符串数组来保存文件中的所有行,然后将每一行解析为列。从那里,您可以测试每一列以查看它是否为整数。

如果您不知道文件中的行数,请使用realloc 在运行时分配所需的内存。此示例读取文件中的所有行,并将其复制到行数组中:

int main()
{
    FILE *f = fopen("test.txt", "r");
    char **lines = 0;
    int lines_size = 0;
    int lines_capacity = 0;
    char buf[1024];
    while (fgets(buf, sizeof(buf), f))
    {
        int len = strlen(buf);
        if (!len) continue;
        if (lines_size == lines_capacity)
        {
            lines_capacity += 16;
            lines = realloc(lines, lines_capacity * sizeof(char*));
        }

        lines[lines_size] = malloc(len + 1);
        strcpy(lines[lines_size], buf);
        lines_size++;
    }

    int i;
    for (i = 0; i < lines_size; i++)
        printf("%s", lines[i]);
    printf("\n");

    for (i = 0; i < lines_size; i++)
        free(lines[i]);
    free(lines);
    return 0;
}

只要文件中的行长度不超过1024,这将起作用。另外,您可以使用strtok 解析每一行

void parseline(char *line)
{
    char copy[1024];
    strcpy(copy, line);
    char *token = strtok(copy, " \n");
    while (token)
    {
        printf("[%s], ", token);
        token = strtok(NULL, " \n");
    }
    printf("\n");
}

【讨论】:

  • @KamiKaze 提问者在另一部分提到了数组。我应该问这是否适用于具有特定链表要求的作业。与向量式内存管理相比,链表使用起来很复杂,速度也很慢。
  • 是的,这是我的错,这就是为什么我如此执着于使用链表
  • 无论如何谢谢你对二维数组的建议它应该是有用的
  • @BarmakShemirani 用链表来做这件事也不是很有用,但我想把数组弄直是它的第一部分,这应该可以。
【解决方案2】:

你需要一个链表中的链表。 Barmak 写了如何获取数据。所以这里是如何获取链表。

struct sString{ 
char* str;
void* next_hor;
void* next_ver;
};
struct sInt{ 
char* Int;
void* next_hor;
void* next_ver;
};

in first column
if ( check  type of column)
    {for each row
      {
       generate corresponding struct and link it to previous element (add-function) 

      }
    }
for other columns
{
  ( check  type of column)
    {for each row
      {
       generate corresponding struct and link it to previous element (add-function) 
       also iterate though linked list and insert the horizontal link

      }
    }
}

它非常集群,有大量开销并且难以管理,但它应该可以工作。

垂直指针也可以是正确的类型,因为类型在列中不会改变。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多