Problem implementing a chained list - list insertion

Asked

Viewed 234 times

1

I’m trying to accomplish this implementation in C. I’m having two problems.

First: Inside the main, I log the data I want and when I go to insert in the list I get a problem.

Second: My data reading function "print_data" gives error when compiling. I am using codeblocks and appears the following message "invalid type argument of '->'".

I partially understand that "->" is pointer signaling and that to access my record data is not necessary the pointer, since the node was accessed and we are looking for the internal statical information. However, I would like a more detailed explanation if possible.

    #include <stdio.h>
    #include <stdlib.h>

    typedef struct registro_st{         // sequência de objetos do mesmo tipo
        char login[50];
        char nome[50];
        float valor;
        struct registro *prox;
    } registro;

    typedef struct nodo_st{
        registro dado;
    struct nodo *prox;
    } nodo;

    typedef struct Lista_st{
        nodo *cabeca;
        nodo *cauda;
    int tamanho;
    } lista;


    nodo* CriarNodo(registro p){

            nodo* n;
            n = (nodo*)malloc(sizeof(nodo));
            n->dado = p;
            n->prox= NULL;
    return n;
    }

    void criarLista(lista *l){
            return NULL;
    }

    void insere_ini(lista *l, registro dado){
        nodo* novo = (nodo*)malloc(sizeof(nodo));
            if(novo=NULL){
                return 0; //falta de espaço
            };
            novo->dado = dado;
            novo->prox = l->cauda; //antigo primeiro aponta para o próximo
            l->cauda = novo; // novo nodo recebe ponteiro para começo
            return novo;



    }

    //FUNÇÕES PARA UTILIZAR NO MAIN

    void imprime_nomes(nodo* lista){            // função que imprime os valores
        nodo* p;
            for(p = lista; p != NULL; p = p->prox){
                printf("Nome eh: %s\n", p->dado->nome);
            }
    }
    void criar_registro(registro *p){
        printf("Qual login para registro:\n");
        scanf("%s", &p->login);
        printf("Qual o nome do contato:\n");
        scanf("%s", &p->nome);
        printf("Qual valor para registrar:\n");
        scanf("%f", &p->valor);
    }


    int main(){

    registro p1_main;
    lista   p2_main;
    nodo p3_main;

    char escolha;

    printf("Gostaria de registrar contatos?\n");
    printf("Digite -->>!! sim!! <<-- para registrar e -->>!! não !!<<-- para sair.\n");
    scanf("%s", &escolha);

    criarLista(&p2_main);

    do  {
        criar_registro(&p1_main); //poderia usar esta forma alternativa registro *novoRegistro = criar_registro()

        insere_ini(&p2_main, p1_main);
        }

        while(escolha != "nao");
    }

1 answer

2


Let’s go in pieces.

First, in print_names the use of for in this case is a bad practice of programming, because you do not know the number of elements that will have the chain list. For this case, use the while thus:

void imprime_nomes(nodo* lista) // função que imprime os valores
{ 
    nodo* p = lista;
    while (p)
    {
        printf("Nome eh: %s\n", p->dado->nome);
        p = p->prox;
    }
}

Second, the problem lies in the statement of the structure nodo_st. You should point out the member datum as a pointer, and not as a die by itself. That’s why I was giving the problem with the pointer arrow (->), because the structure was not indicated as pointer in the way it should. This will stay that way:

typedef struct nodo_st
{
    registro * dado;
}

Third, the parameter used in Child must be a pointer, and therefore must have an asterisk before the variable name:

nodo* CriarNodo(registro * p)
{
        nodo* n;
        n = (nodo*)malloc(sizeof(nodo));
        n->dado = p;
        n->prox= NULL;
        return n;
}

The same occurs in function insere_ini. Fix it, stay like this:

void insere_ini(lista *l, registro * dado)
{
    nodo* novo = (nodo*)malloc(sizeof(nodo));
        if(novo=NULL){
            return 0; //falta de espaço
        };
        novo->dado = dado;
        novo->prox = l->cauda; //antigo primeiro aponta para o próximo
        l->cauda = novo; // novo nodo recebe ponteiro para começo
        return novo;
}

Finally, it is also necessary to adjust this operation for the modifications made, indicating the arguments as pointers:

insere_ini(&p2_main, &p1_main);

This will still generate multiple Warnings that you will have to correct gradually. I recommend an in-depth study of pointers, as it is one of the most essential knowledge for programming well in C.

  • 1

    In the case of "print_names(node* list)" there is a "list" pointer that points to nodes and a "p" pointer that points to nodes as well. Why is that? What parameter I printed should receive?

  • Well observed. As in print_names you will iterate in a chained list for each element, the correct is to put the parameter list function within the pointer p in this way: nodo *p = lista;, or even use the parameter itself list within the function instead of the variable p. The two possibilities are correct. I edited the answer as indicated.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.