链表的向量不能正常工作

时间:2016-10-16 19:39:38

标签: c linked-list grammar

我是C编程的初学者,我正在尝试创建一个算法来查找第一个跟随给定语法的集合将在.txt文件中。

输入语法如下所示:

S-abA|e|bhG|AKX
A-Kb|d
K-j|c|e
X-p

到目前为止,我只是试图定义我将用于查找这些集合的结构(以及我遇到的问题)。

我使用列表向量,其中每个列表将包含我的语法的RHS值,并且向量中的每个位置(由输入文件中的规则或行数定义)将是指针到列表。 下面的函数编译并且几乎有效。正在正确阅读作品和变量" producao"工作正常,我已经尝试将其打印出来并正确地获得每个值,但是当我将这些值添加到列表中时,当我打印整个列表时,我最终得到的是: enter image description here

我应该拥有的是: enter image description here

我遇到问题的功能发布在下面:

criaListaRegras()
{
    lista *regras;
    regras = cria_lista(); // initialize list pointing to null
    lista **vetor; // declare the vector of list pointers
    vetor = malloc(sizeof(lista)*numLinhas);

    int i = 0;
    int numLinha = 0;
    char producao[10]; // Each production in the RHS will have at most 9 characters and will be added to this variable, one at a time.
    FILE *entrada;
    entrada = fopen("entrada.txt", "r"); // input file
    fseek(entrada, 2, SEEK_SET); // seek to RHS of the rule. (S-ab|AbB), makes fp go to 'a'.
    char linha; // Will be used to parse the input

    while ((linha = getc(entrada)) != EOF){
        if (linha == '\n'){ // checks if a rule has ended, so that we add end of string to production and append that into the list.
            producao[i] = '\0';
            inserir(regras, producao); // append production (producao) into the list (regras).
            imprimir(regras); // should print all values inside "regras" but only print the last value added * "number of productions found so far".
            vetor[numLinha] = regras; // should assign a list into its position in the pre-defined vector of lists at position "numLinha".
            i = 0; // resets string position counter to 0 so we can reuse it for next production.
            numLinha++; // increment line/rule counter.
            fseek(entrada, 2, SEEK_CUR);
        }
        if (linha == '|'){ // our production delim is '|', so if we find it, means a production has ended and we should add it into the list.
            producao[i] = '\0';
            inserir(regras, producao);
            i = 0;
        }
        if(linha != '|' && linha != '\n'){ // this means the current char (linha) is part of some RHS production, so we should concatenate it into the variable producao on position 'i' and increment 'i'.
            producao[i] = linha;
            i++;
        }
    }
}

criaListaRegras()中使用的其他函数对于测试值工作正常,可以在下面找到:

lista *cria_lista()
{
    lista *novo = (lista*)malloc(sizeof(lista));
    novo->next = NULL;
    return novo;
}

void imprimir(lista *original)
{
    lista * aux = original->next;

    while(aux!= NULL){
        printf("%s\n", aux->nome);
        aux=aux->next;
    }
}

void inserir(lista *original, char *nome)
{
    lista *base = original;
    lista *aux = original->next;
    lista *novo;

    while(aux!= NULL){
        aux=aux->next;
        base=base->next;
    }

    novo=(lista*)malloc(sizeof(lista));
    novo->nome = nome;
    novo->next = aux;
    base->next = novo;
}

如果有人能指出我在那里做错了什么,我会很高兴。

1 个答案:

答案 0 :(得分:0)

查看提供源代码并使用criaListaRegras()函数构建完整示例,我检测到多个错误,并且可能会创建观察到的输出。

假设1 - 如何声明结构lista

在解析源代码时,lista有2个属性next(用于链表机制)和nome来存储加载的“producao”(char producao [10]; )。

typedef struct slista {
    char *nome; // or char nome[10];
    struct slista *next;
} lista;

问题1 - 附加到lista结构,函数inserir()不存储char *nome参数的内容,只存储指针。

novo=(lista*)malloc(sizeof(lista));
novo->nome = nome; // ERROR storing the pointer
novo->next = aux;
base->next = novo;

通过存储char *nome参数的指针(它是局部变量char producao[10];的指针),每个节点lista将具有指针值,并且在使用{{1}时},imprimir()将指向最后一个条目(对于aux->nome,它是"S-abA|e|bhG|AKX",...)。

解决方案1.1 - 如果"AKX"的属性声明为lista,则需要分配字符串并复制内容。

  

最简单的解决方案是使用能够分配和复制的char *nome;   字符串。

strdup()

解决方案1.2 - 如果novo=(lista*)malloc(sizeof(lista)); novo->nome = strdup(nome); // allocate and copy novo->next = aux; base->next = novo; 的属性声明为lista,则只需要复制字符串。

  

输入(来自char nome[10];)仅限于(10-1)char producao[10];和   可以使用函数char轻松复制。

strcpy()

其他检测到的问题:

1 - 分配novo=(lista*)malloc(sizeof(lista)); strcpy(novo->nome,nome); // copy from nome to novo->nome novo->next = aux; base->next = novo; vetor

  

变量listalista **vetor;的数组而不是   lista *

lista

而不是

lista **vetor; // declare the vector of list pointers
vetor = (lista **)malloc(sizeof(lista *)*numLinhas);

2 - 在使用lista **vetor; // declare the vector of list pointers vetor = (lista **)malloc(sizeof(lista)*numLinhas); 之后和阅读数据之前检查FILE *entrada;值。

3 - fopen()中存储完整的lista *regrasvetor[numLinha] = regras;)后,您需要创建一个新的。{/ p>

  

再次致电vetor

regras = cria_lista();