Chained list - Error inserting element - [Warning] Passing argument 1 of 'strncpy' makes Pointer from integer without a cast

Asked

Viewed 596 times

0

Good afternoon, would you be kind enough to help me with my project? I have to create a chained list that records bus schedule data, but when I try to execute, soon after entering the time data appears an error, as below: Print erro

When I try to compile some warnings appears that I could not intend, image below: In orange - [Warning] Passing argument 1 of 'strlen' makes Pointer from integer without a cast

Print erro 2

I’ll put the code down:

main. c

//Bibliotecas utilizadas
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "lista.h"

 //Inicializando os dados da lista
Dados *principal = NULL;

//---------------------------------
//     Função Principal
//---------------------------------

int main(void) {
    char escolha;
    int chave=0;
    //Laço que irá mostrar o menu esperando uma opção (char)
    do {
        //Limpando a tela, e mostrando o menu lembrando que primeiramente, os itens estão bloqueados até que seja criada uma lista vazia
        LIMPA_TELA;
        fprintf(stdout, "\n\t\tHorario de onibus\n\n");
        fprintf(stdout, "Escolha uma opcao: \n");
        fprintf(stdout, "1 - Criar lista vazia\n");
        if(chave==1){
            fprintf(stdout, "2 - Inserir no Inicio de uma lista\n");
            fprintf(stdout, "3 - Inserir no Fim de uma lista\n");
        }
        fprintf(stdout, "4 - Lista Vazia...\n");
        if(chave==1){
            fprintf(stdout, "5 - Exibir dados do primeiro elemento\n");
            fprintf(stdout, "6 - Exibir dados do ultimo elemento\n");
            fprintf(stdout, "7 - Exibir todos os valores da Lista\n");
            fprintf(stdout, "8 - Exibir o tamanho da Lista\n");
            fprintf(stdout, "9 - Eliminar primeiro elemento\n");
            fprintf(stdout, "a - Eliminar último elemento\n");
            fprintf(stdout, "b - Eliminar elemento buscado\n");
            fprintf(stdout, "c - Busca Dados\n");
        }
        fprintf(stdout, "d - Sair\n\n");
        fprintf(stdout, "Resposta: ");
        scanf("%c", &escolha);
        //Se a chave for diferente de zero, porém a escolha for diferente de 1, 4 e d, a escolha será z (opção inválida)
        if((chave==0)&&((escolha!='1')&&(escolha!='d')&&(escolha!='4')))
            escolha='z';

        switch(escolha) {
            //Criando lista vazia
            case '1':
                chave=1;
                criavazia(); 
                break;
            //Inserindo no início
            case '2':
                insereinicio();
                break;                
            //Inserindo no final
            case '3':
                //Se a lista não estiver vazia
                if(principal!=NULL){
                    inserefim();
                }
                //senão inclui no inicio
                else{
                    insereinicio();
                }
                break;
            //Checando se a lista está vazia
            case '4':
                listavazia();
                break;
            //Mostrando Primeiro elemento
            case '5':
                prielemento();
                break;
            //Mostrando Último elemento
            case '6':
                ultelemento();
                break;
            //Exibindo todos elementos
            case '7':
                exibe();
                break;
            //Exibindo tamanho da lista
            case '8':
                exibetam();
                break;
            //Deleta primeiro elementos
            case '9':
                deletapri();
                break;                
            //Deleta último elemento
            case 'a':
                deleta();
                break;
            //Deleta elemento buscado
            case 'b':
                delbusca();
                break;                
            //Buscando elementos
            case 'c':
                busca();
                break;
            //Saindo e finalizando o programa
            case 'd':
                fprintf(stderr,"Obrigado por utilizar esse programa!\n");
                fprintf(stderr,"------>Terminal de Informação<------\n\n");
                ESPERA;
                //exit(0);
                break;
            //Se foi algum valor inválido
            default:
                fprintf(stderr,"Digite uma opcao valida (pressione -Enter- p/ continuar)!\n");
                getchar();
                break;
        }
        //Impedindo sujeira na gravação da escolha
        getchar();
    }
    while (escolha > 0); //Loop Infinito
    return 0;
}

list. h

//Se o sistema for Windows adiciona determinada biblioteca, e definindo comandos de limpar e esperar
#ifdef WIN32
    #include <windows.h>
    #define LIMPA_TELA system("cls")
//Senão for Windows (ex.: Linux)
#else
    #include <unistd.h>
    #define LIMPA_TELA system("/usr/bin/clear")
#endif

//Máximo de bytes para uma String
#define BUFFER 64

//Espera 3 segundos
#define ESPERA sleep(3)

//Estrutura da lista que será criada
typedef struct lista {
    char *nome;
    char horario;
    float preco;
    struct lista *proximo;
} Dados;

extern Dados *principal;

//Funções para manusear os dados (irão retornar dados)
Dados *inicia_dados  (char *nome, char horario, float preco);
Dados *insere_dados  (Dados *dados, char *nome, char horario, float preco);
Dados *delbusca_dados(Dados *dados, char *chave);
Dados *deleta_dados  (Dados *dados, int nTipo);
int   checa_vazio    (Dados *dados);

//Funções para mostrar dados
void  exibe_dados    (Dados *dados);
void  exibe_tamanho  (Dados *nova);
void  busca_dados    (Dados *dados, char *chave);

//Funções do Menu
void criavazia(void);    //1
void insereinicio(void); //2
void inserefim(void);    //3
void listavazia(void);   //4
void prielemento(void);  //5
void ultelemento(void);  //6
void exibe(void);        //7
void exibetam(void);     //8
void deletapri(void);    //9
void deleta(void);       //a
void delbusca(void);     //b
void busca(void);        //c

list. c

//Bibliotecas utilizadas
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "lista.h"

//---------------------------------
//     Opção '1'
//---------------------------------

//Criando uma lista vazia
void criavazia(void){
    char *nome;
    char horario;
    float preco;
    //Alocando dados para uma String
    nome = (char *)malloc(BUFFER);
    //Lendo String Nome
    fprintf(stdout, "\n\nDigite o Nome: \n----> ");
    scanf("%s", nome);
    fprintf(stdout, "\n");
    //Lendo String horario
    fprintf(stdout, "\n\nDigite o Horario: \n----> ");
    scanf("%s", horario);
    fprintf(stdout, "\n");
    //Lendo float preco
    fprintf(stdout, "Digite a preco: \n----> ");
    scanf("%f", &preco);
    fprintf(stdout, "\n");

    //Lançando os dados lidos na lista Principal
    free(principal);
    principal = inicia_dados(nome, horario, preco);
}

//Iniciando os dados da lista vazia
Dados *inicia_dados(char *nome, char horario, float preco) {
    Dados *novo;
    //Alocando memória para a posição atual da lista
    novo = (Dados *)malloc(sizeof(Dados));
    //Lançando os dados lidos
    novo->nome = (char *)malloc(strlen(nome)+1);
    strncpy(novo->nome, nome, strlen(nome)+1);
    strncpy(novo->horario, horario, strlen(horario)+1);
    novo->preco = preco;
    //Apontando para a próxima posição da lista
    novo->proximo = NULL;
    return novo;
}

//---------------------------------
//     Opção '2'
//---------------------------------

//Inserindo no início da lista
void insereinicio(void){
    char *nome;
    char horario;
    float preco;
    //Reservando espaço para String
    nome = (char *)malloc(BUFFER);
    //Armazenando String Nome
    fprintf(stdout, "\n\nDigite o Nome: \n----> ");
    scanf("%s", nome);
    fprintf(stdout, "\n");
    //Armazenando String Horario
    fprintf(stdout, "\n\nDigite o Horario: \n----> ");
    scanf("%s", horario);
    fprintf(stdout, "\n");
    //Armazenando int preco
    fprintf(stdout, "Digite a preco: \n----> ");
    scanf("%f", &preco);
    fprintf(stdout, "\n");
    //Lançando dados no ínicio da lista
    principal = insere_dados(principal, nome, horario, preco);
}

//Inserindo dados recebidos
Dados *insere_dados(Dados *dados, char *nome, char horario, float preco) {
    Dados *inicio;
    //Alocando memória para a posição atual
    inicio = (Dados *)malloc(sizeof(Dados));
    //Lançando os dados lidos
    inicio->nome = (char *)malloc(strlen(nome)+1);
    strncpy(inicio->nome, nome, strlen(nome)+1);
    strncpy(inicio->horario, horario, strlen(horario)+1);
    inicio->preco = preco;
    //O próximo valor aponta para a lista já existente
    inicio->proximo = dados;
    return inicio;
}

//---------------------------------
//     Opção '3'
//---------------------------------

//Inserção de dados no final de uma lista
void inserefim(void) {
    char *nome;
    char horario;
    float preco;
    //Alocação de espaço para String Nome
    nome = (char *)malloc(BUFFER);
    //Armazenando String Nome
    fprintf(stdout, "\n\nDigite o Nome: \n----> ");
    scanf("%s", nome);
    fprintf(stdout, "\n");
    //Armazenando String Horario
    fprintf(stdout, "\n\nDigite o Horario: \n----> ");
    scanf("%s", horario);
    fprintf(stdout, "\n");
    //Armazenando Float preco
    fprintf(stdout, "Digite a preco: \n----> ");
    scanf("%f", &preco);
    fprintf(stdout, "\n");
    //Criando listas auxiliares        
    Dados *final,*aux;
    //Alocando dados para a posição final da lista
    final = (Dados *)malloc(sizeof(Dados));
    //Setando os valores Nome e preco
    final->nome = (char *)malloc(strlen(nome)+1);
    strncpy(final->nome, nome, strlen(nome)+1);
    strncpy(final->horario, horario, strlen(horario)+1);
    final->preco = preco;
    //A proxima posição será Nulo
    final->proximo=NULL;
    //A lista auxiliar será igual a Principal
    aux=principal;
    //Enquanto o próximo de auxiliar não for Nulo
    while(aux->proximo!=NULL){
        aux=aux->proximo;
    }
    //O último valor, será Nulo, e depois apontando para
    //o Final
    aux->proximo=NULL;
    aux->proximo=final;
}

//---------------------------------
//     Opção '4'
//---------------------------------

//Função que testa se a lista está vazia
void listavazia(void){
    if (principal == NULL) 
        fprintf(stdout, "\n\nLista esta Vazia!\n\n ");
    else
        fprintf(stdout, "\n\nLista nao esta Vazia!\n\n ");
    getchar();
}

//---------------------------------
//     Opção '5'
//---------------------------------

//Mostrar o primeiro elemento da lista
void prielemento(void){
    fprintf(stdout, "------------------------\n");  
    fprintf(stdout, "Nome: %s\n", principal->nome);
    fprintf(stdout, "Horario: %s\n", principal->horario);
    fprintf(stdout, "preco: %d\n", principal->preco);
    fprintf(stdout, "------------------------\n");
    getchar();
}

//---------------------------------
//     Opção '6'
//---------------------------------

//Mostrando o último elemento da lista
void ultelemento(void){
    Dados *aux=principal;
    //Enquanto o próximo elemento não for NULL
    //Avance uma posição
    while(aux->proximo!=NULL){
        aux=aux->proximo;
    }
    fprintf(stdout, "------------------------\n");  
    fprintf(stdout, "Nome: %s\n", aux->nome);
    fprintf(stdout, "Horario: %s\n", aux->horario);
    fprintf(stdout, "preco: %d\n", aux->preco);
    fprintf(stdout, "------------------------\n");
    getchar();
}

//---------------------------------
//     Opção '7'
//---------------------------------

//Exibindo dados da lista
void exibe(void) {
    //Se não estiver vazio, exibe os dados
    if (!checa_vazio(principal))
        exibe_dados(principal);
}

//Exibindo todos os dados do menu
void exibe_dados(Dados *dados) {
    fprintf(stdout, "Cadastro de onibus:\n\n");
    fprintf(stdout, "------------------------\n");
    //Exibindo todos os valores da lista
    for (; dados != NULL; dados = dados->proximo) {
        fprintf(stdout, "Nome: %s\n", dados->nome);
        fprintf(stdout, "Horario: %s\n", dados->horario);
        fprintf(stdout, "preco: %d\n", dados->preco);
        fprintf(stdout, "------------------------\n");
    }
    getchar();
}

//---------------------------------
//     Opção '8'
//---------------------------------

//Exibindo o tamanho da lista
void exibetam(void){
    //Se não estiver vazio, exibe os dados
    if (!checa_vazio(principal))
        exibe_tamanho(principal);
}

//Exibindo o tamanho total (bytes) e quantpreco
void exibe_tamanho(Dados *nova){
  int aux=0, tamanho=0;
  fprintf(stdout, "\n------------------------\n");
  //Correndo todos os valores da Lista
  for (; nova != NULL; nova = nova->proximo) {
    aux++;
    tamanho+=sizeof(nova);
  }
  fprintf(stdout, "Total de Elementos: %d\nTamanho Total: %d bytes\n",aux,tamanho);
  fprintf(stdout, "------------------------\n");
  getchar();
}

//---------------------------------
//     Opção '9' e 'a'
//---------------------------------

//Deleta o Primeiro valor
void deletapri(void) {
    //Se não estiver vazio, deleta os dados
    if (!checa_vazio(principal))
        principal = deleta_dados(principal,1);
}

//Deleta o Último valor
void deleta(void) {
    //Se não estiver vazio, deleta os dados
    if (!checa_vazio(principal))
        principal = deleta_dados(principal,2);
}

//Deleta registros da lista, Tipo 1 = Inicio, Tipo 2 = Fim
Dados *deleta_dados(Dados *dados, int nTipo) {
    if(nTipo==1){
        //Apontando para a próxima posição
        Dados *novo;
        novo = dados->proximo;
        //Limpando os dados
        free(dados->nome);
        free(dados);
        fprintf(stdout, "O primeiro registro foi deletado  com sucesso.\n");
        getchar();
        return novo;
    }
    if(nTipo==2){
        Dados *novo=dados, *aux=dados;
        //Se a lista estiver no fim, exclui o que restou
        if(novo->proximo==NULL){
            free(novo);
            aux=NULL;
        }
        else{
            //Laço de repetição para chegar no fim da lista
            while(novo->proximo!=NULL){
                novo=novo->proximo;
            }
            //Preenchendo os dados da lista auxiliar
            while(aux->proximo!=novo){
                aux=aux->proximo;
            }
            //Limpando os dados e apontando para nulo
            free(novo);
            aux->proximo=NULL;
        }
        fprintf(stdout, "O ultimo registro foi deletado com sucesso.\n");
        getchar();
        return aux;
    }
}

//---------------------------------
//     Opção 'b'
//---------------------------------

//Deletando valor buscado
void delbusca(void) {
    char *chave;
    //Se não estiver vazio
    if (!checa_vazio(principal)) {
        chave = (char *)malloc(BUFFER);
        //Armazenando o valor digitado
        fprintf(stdout, "Digite o nome para buscar: \n--> ");
        scanf("%s", chave);
        //Deletando a chave buscada
        principal = delbusca_dados(principal, chave);
    }
}

//Deletando os valores buscados
Dados *delbusca_dados(Dados *dados, char *chave) {
    int achou=0,cont=0;
    Dados *juntou, *aux, *nova=dados;        

    //Correndo a lista e verificando se encontrou a string buscada, se sim, aumenta o contador e seta a variável de busca
    for (; nova != NULL; nova = nova->proximo) {
        if (strcmp(chave, nova->nome) == 0) {
            achou=1;
            cont++;
        }
    }

    //Se encontrou a busca
    if(achou==1){
        int ind=0;
        //Correndo a lista
        for(ind=0;ind<cont;ind++){
            //Se encontrou na primeira casa apaga a primeira casa
            if(strcmp(chave,dados->nome)==0){
                aux=dados;
                dados=dados->proximo;
                free(aux);
            }
            //Senão, procura até encontrar
            else{
                aux=dados;
                //Posiciona na frente do encontro para exclusão
                while(strcmp(chave,aux->nome)!=0){
                    aux=aux->proximo;
                }

                juntou=dados;
                //Enquanto o auxiliar juntou for diferente do posicionado para exclusão
                while(juntou->proximo!=aux){
                    juntou=juntou->proximo;
                }
                //Aponta para o próximo valor válido
                juntou->proximo=aux->proximo;

                free(aux);
            }
        }
        fprintf(stdout, "Excluido.\n");
    }
    else
        fprintf(stdout, "Nenhum resultado encontrado.\n");

    getchar();
    return dados;
}

//---------------------------------
//     Opção 'c'
//---------------------------------

//Função que busca os dados
void busca(void) {
    char *chave;
    //Senão estiver vazio a lista
    if (!checa_vazio(principal)) {
        chave = (char *)malloc(BUFFER);
        //Lendo o nome que será buscado
        fprintf(stdout, "Digite o nome para buscar: \n--> ");
        scanf("%s", chave);
        //chamando a função que irá procurar o nome
        busca_dados(principal, chave);
    }
}

//Percorre cada ponta da lista verificando busca
void busca_dados(Dados *dados, char *chave) {
    int achou = 0;
    fprintf(stdout, "Cadastro:\n\n");
    //Percorrendo todas as posições
    for (; dados != NULL; dados = dados->proximo) {
        //Se encontrou, mostra os dados
        if (strcmp(chave, dados->nome) == 0) {
            fprintf(stdout, "------------------------\n");
            fprintf(stdout, "Nome: %s\n", dados->nome);
            fprintf(stdout, "Horario: %s\n", dados->horario);
            fprintf(stdout, "preco: %f\n", dados->preco);
            fprintf(stdout, "------------------------\n");
            achou++;
        }
    }

    //Mostrando o resultado da busca
    if (achou == 0)
        fprintf(stdout, "Nenhum resultado encontrado.\n");
    else
        fprintf(stdout, "Foram encontrado(s) %d registro(s).\n", achou);

    getchar();
}

//---------------------------------
//     Função Auxiliar
//---------------------------------

//Função que testa se a lista esta vazia
int checa_vazio(Dados *dados) {
    //Se a lista estiver vazia
    if (dados == NULL) {
            fprintf(stdout, "Lista vazia!\n");
            getchar();
            return 1;
    } else
            return 0;
}
  • 1

    First error I found is that your time is a char of 1 character and not a string

  • @Andrelacomski This is the error mentioned by Warning, which directly answers the question. Formalize an answer with this.

  • Got it personal was the issue of the string itself, thank you very much! @Andrelacomski and Isac

2 answers

1


The problem is in the following call of the strlen function':

strncpy(new->time, time, strlen(time)+1);

In this case, the time argument is not of the type expected by the strlen function. The 'strlen' function waits for a char pointer, 'const char *', but you provide a 'char''.

To illustrate the problem, I did the small program below. Here you will see that in the compilation by Mingw (used by Code::Blocks) the same 'Warning' will occur. When running the program, the first 'printf' will run successfully, but the second (with char argument) will cause the same error you are having.

#include <stdio.h>
#include <string.h>

int main(int argc, char* argv[])
{
    char *s = "abc";
    printf("Tamanho de s: %d", strlen(s));

    char c = 'a';
    printf("Tamanho de c: %d", strlen(c));

    return 0;
}
  • 1

    I did as you said and it worked, thank you very much! @alandplm

0

Is it my impression or did you forget to release the memory allocated by the list? Although it is practically not necessary, it is very timely.

I also, for practicality, usually use a single chained list, but of the type cell*, in global scope to work, so the procedure below is parameter empty. For those who choose to provide the address of a local list to a function, however, just make some adjustments to this algorithm.

void free_llist(void)
{
    if (linked_list)
    {
        cell* aux = linked_list;

        while (linked_list)
        {
            aux = linked_list;
            linked_list = linked_list->next;
            free(aux);
            aux = (cell*) 0;
        }

        free(linked_list);
        linked_list = (cell*) 0;
    }

    return;
}

Browser other questions tagged

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