从文件创建链接列表时,程序总是崩溃

时间:2019-05-14 12:39:55

标签: c file pointers linked-list

我正在尝试编写一个程序,将文件的每一行的第一个条目(条目之间用/分隔)放入链接列表中,但很不幸未能这样做。

第一个“ while”周期运行良好,但是此后完全崩溃。我尝试了多种方法,但到目前为止都没有奏效。任何帮助将不胜感激,因为我要强调很多无法做这种简单的事情

提前谢谢!

t_local *cria_cabecalhoL(void){
    t_local *lista = (t_local*)malloc(sizeof(t_local));
    if (lista != NULL)
        lista->next = NULL;
    return lista;
}
typedef struct local{
    char *name;
    struct local *next;

}t_local;


void createlistlocals(t_local *header_l){
    FILE *fp;
    t_local *aux;
    t_local *aux1;
    aux1 = header_l;
    char *line = malloc(150*sizeof(char));
    char *name1 = malloc(150*sizeof(char));
    char c;
    fp = fopen("locais.txt","r");
    fgets(linha, 150, fp);
    while (strcmp(line, "end")!=0){
        puts(line);
        name =strtok(line, "/");
        puts(name1);
        aux->name = strdup(name1);
        aux->next = aux1->next;
        aux1->next= aux;
        aux1 = aux;
        fgets(line, 150, fp);
    }
    aux1 = header_l;

}


int main()
{
    t_local *header_l = cria_cabecalhoL();
    createlistlocals(header_l);

}

2 个答案:

答案 0 :(得分:0)

好的,这是解决结构最明显问题的粗略尝试。

t_local * createlistlocals(const char *filename)
{
    FILE * const fp = fpoen(filename, "rt");
    if (fp == NULL)
     return NULL;
    t_local *head = NULL;
    char line[150];
    while (fgets(line, sizeof line, fp) != NULL)
    {
      const char * const slash = strchr(line, '/');
      if (slash == NULL)
        break;
      t_local * const node = malloc(sizeof *node);
      if (prev != NULL)
      {
        prev->next = node;
      }
      else
      {
        head = node;
      }
      *slash = '\0';
      node->name = strdup(line);
      prev = node;
    }
    fclose(fp);
    return head;
}

这也将任何不匹配的行(例如,没有斜线的行)视为结束标记。这将包括end

与执行I / O和内存分配的任何代码一样,它可以变得更健壮。 :)

这将返回列表,其中第一行的数据在第一个节点中,依此类推,并接受文件名,而不是硬编码文件名并接受初始列表节点。这对我来说更清楚和有用。

答案 1 :(得分:0)

看看这个循环,似乎有几个错误。

  • 您创建了一个头节点,但是在读取时不会为每行分配额外的内存
  • 似乎第一次迭代使用的是未初始化的指针(可能是崩溃或内存损坏)。
  • 下一次迭代似乎使用了空指针(几乎肯定会崩溃)。

注释循环:

void createlistlocals(t_local *header_l){
    FILE *fp;
    t_local *aux;
    t_local *aux1;
    aux1 = header_l; // aux1 = head, aux is uninitialised
    char *line = malloc(150*sizeof(char)); // needs to be freed at the end
    char *name1 = malloc(150*sizeof(char));
    char c;

    fp = fopen("locais.txt","r");
    fgets(line, 150, fp); // assumuming linha == line

    // Note, there are ways to loop until the actual file end rather thna a "special line"
    while (strcmp(line, "end")!=0){ 
        puts(line);
        name1 =strtok(line, "/"); // Assuming the rest of the line is not important.
        puts(name1);

        // aux was uninitialised, so this will be undefined behaviour and either crash or
        // overwrite something (memory corruption) that may cause strange things later
        // (including crashes)
        aux->name = strdup(name1);
        // cria_cabecalhoL set header_l->next to null, so this is not actually creating a new node.
        // and the next loop will actually try to use null->name and that is basically garunteed
        // to crash on most systems.
        aux->next = aux1->next;

        aux1->next= aux;
        aux1 = aux;
        fgets(line, 150, fp); // This is duplicate, could be once at the start of the loop, maybe use for(...) loop
    }
    aux1 = header_l; // Note, assigning a local here at the end doesn't do anything

}

修正与链表相关的错误,并假设t_local->name == NULL是您的最终标记值。

t_local *cria_cabecalhoL(void){
    t_local *lista = (t_local*)malloc(sizeof(t_local));
    if (lista != NULL)
        lista->name = NULL; // no data, empty node
        lista->next = NULL;
    return lista;
}
void createlistlocals(t_local *header_l){
    FILE *fp;
    t_local *node = header_1;
    t_local *next;
    char *line = malloc(150*sizeof(char)); // needs to be freed at the end
    char *name1;

    fp = fopen("locais.txt","r");
    fgets(line, 150, fp);

    while (strcmp(line, "end")!=0){ 
        puts(line);
        name1 =strtok(line, "/");
        puts(name1);

        node->name = strdup(name1);
        // And create a new empty node for the next loop
        next = cria_cabecalhoL();
        node->next = next; // New node comes after the current one.
        node = next; // And now using the next node on loop

        fgets(line, 150, fp);
    }
}