Ir para conteúdo
Fah

Lista simplesmente encadeada tendo como argumento outra estrutura com dados

Recommended Posts

Boa Noite Pessoal!

Estou com dificuldade em implementar um exercício de lista simplesmente encadeada.  Nele pede para criar uma estrutura com os dados de um aluno (matricula, nome e media), e outra para ser a lista (com a estrutura com os dados do aluno e um no com as informações do próximo nó). Uma das opções é para inserir os dados de um novo aluno em ordem crescente de matricula. O código está dando erro. Vocês conseguem me dizer onde estou errando? Vejam meu código:

 

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct aluno{
    int matricula;
    char nome[100];
    float media;
};
typedef struct aluno Aluno;

struct no{
    Aluno* dados;
    struct no* prox;
};
typedef struct no No;
No* cria(No* l){
No* p=(No*)malloc(sizeof(No));
p->dados=NULL;
return l;
}
No* ins_ordenado(No* l,int mat,char* nome,float nota){
    Aluno* Al=(Aluno*)malloc(sizeof(Aluno));
    No* novo=(No*)malloc(sizeof(No));
    int i=0;
    Al->matricula=mat;
    while(nome!='\0'){
       Al->nome=nome;
       i++;
    }
    Al->nome=NULL;
    Al->media=nota;
    novo->dados=Al;
    No*p=l;
    No*aux=NULL;
    if(l==NULL){
        novo->prox=l;
        return novo;
    }
        while(p!=NULL&&p->dados->matricula<Al->matricula){
              aux=p;
              p=p->prox;
        }
        novo->prox=aux->prox;
        aux->prox=novo;
        if(p==NULL){
            novo->prox=NULL;
        }
    return l;
}
void imprime(No* l){
    No* p;
    printf("turma 1:\n");
    for(p=l;p!=NULL;p->prox){
        printf("Matricula: %d\t Nome: %s Nota:%f\n",p->dados->matricula,p->dados->nome,p->dados->media);
    }
    printf("\n");
}
int vazia(No* l){
    return(l==NULL);
}
int main(){
No* l1=cria(l1);
l1=ins_ordenado(l1,1,"Maria",5);
printf("vazia? %d",vazia(l1));
//imprime(l1);
return 0;
}


 

Desde já, Obrigada!

Compartilhar este post


Link para o post
Compartilhar em outros sites

Dica: ao invés de dizer que está dando erro, seria mais interessante dizer qual erro está dando. Muita coisa é sintaxe incorreta.

 

Antes de sair acessando e atribuindo coisas a ponteiros você faz bem em verificar se o retorno do malloc não é NULL.

Faz muito tempo que não mexo com C, então compila isso com os warnings ligados.

 

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

#define MAXNOME 100
struct aluno{
  int matricula;
  char nome[MAXNOME];
  float media;
};

typedef struct aluno Aluno;

struct no{
  Aluno* dados;
  struct no* prox;
};

typedef struct no No;

No* criar_lista(){
  No* tmp = (No*) malloc(sizeof(No));
  
  if (tmp == NULL) {
    printf("%s\n", strerror(errno));
    exit(1);
  }
  
  tmp->dados = NULL;
  tmp->prox = NULL;
  
  return tmp;
}

Aluno* criar_aluno() {
  Aluno* no_aluno = (Aluno*) malloc(sizeof(Aluno));
  if (no_aluno == NULL) {
    printf("%s\n", strerror(errno));
    exit(1);
  }
  return no_aluno;
}

Aluno* ler_aluno() {
  
  Aluno* no_aluno = criar_aluno();
  
  printf("Informe a matrícula:");
  scanf("%d%*c", &(no_aluno->matricula));
  
  printf("Informe o nome:");
  fgets(no_aluno->nome, 100, stdin);
  (*strrchr(no_aluno->nome, '\n')) = '\0';
  
  printf("Informe a média:");
  scanf("%f", &(no_aluno->media));
  
  return no_aluno;
}

No* inserir_ordenado(No* lista_alunos, Aluno* aluno) {
  if(lista_alunos == NULL) {
    return -1;
  }
  
  int posicao = 0;
  No* elemento = lista_alunos;
  No* anterior = NULL;
  if (elemento->dados == NULL && elemento->prox == NULL) {
    lista_alunos->dados = aluno;
  
  } else {
    
    while (elemento != NULL && elemento->dados->matricula < aluno->matricula) {
      anterior = elemento;
      elemento = elemento->prox;
    }
    
    No * tmp = (No*) malloc(sizeof(No));
    if (tmp == NULL) {
      printf("%s",strerror(errno));
      free(lista_alunos);
      free(aluno);
      exit(1);
    }
    
    tmp->dados = aluno;
    
    if (anterior == NULL) {
      tmp->prox = lista_alunos;
      return tmp;
    } else {
      if (elemento == NULL) {
        tmp->prox = NULL;
        anterior->prox = tmp;
      } else {
        tmp->prox = elemento;
        anterior->prox = tmp;
      }
    }
  }
  
  return lista_alunos;
}

void imprimir(const No* lista_alunos) {
  No* tmp = lista_alunos;
  while(tmp != NULL) {
    if (tmp->dados != NULL) {
      printf("Nome:%s\tMatrícula:%d\tMédia:%.2f\n", tmp->dados->nome, tmp->dados->matricula, tmp->dados->media);
    }
    tmp = tmp->prox;
  }
}

void desalocar(No* l) {
  if (l->prox == NULL) {
    free(l);
    return;
  } else {
    desalocar(l->prox);
    free(l);
  }
}
int main(){
  No* lista_alunos = criar_lista();
  imprimir(lista_alunos);
  
  Aluno * aluno;
  
  for(int i =0 ; i<5; i++) {
    aluno = ler_aluno();
    lista_alunos = inserir_ordenado(lista_alunos, aluno);
  }
  
  imprimir(lista_alunos);
  
  
  free(aluno);
  desalocar(lista_alunos);
  return 0;
}

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

Fah em:

while ( nome!= '\0' ){
Al-> nome= nome;
i ++;
}
Al-> nome= NULL;

Dá erro pois faltam os índices que apontam qual caractére se está a copiar. Faz-se:

while ( nome[i]!= '\0' ){
Al-> nome[i]= nome[i];
i ++;
}
Al-> nome[i]= NULL;

A função cria está errada. Ela retorna o valor do ponteiro que foi passado como argumento sem modificar o valor da região para aonde ele aponta. Isso não é erro porém redundante. O erro está em que a nova lista criada pela função se perde na memória após a função terminar e não se tem controle sobre a nova lista criada.

 

O programa trava ao executar por que na função principal falta inicializar a variável l1 com o valor nulo para que a função de inserção ordenada saiba que a lista está vazia. É:

l1=NULL;

A função de inserção ordenada é redundante pois além de inserir o novo elemento na lista ainda retorna um ponteiro para essa mesma lista. Não está errado mas isso se torna desnecessário a partir da inserção do segundo elemento da lista e em diante até que se resolva adicionar algum com número de matrícula menor do que todos os outros.

 

O programa vai travar toda vez que inserir um valor com número de matrícula menor do que todos os outros que já tem na lista. Isso por que o ponteiro próximo apontado pelo ponteiro novo na função inserção ordenada está recebendo como apontamento outro ponteiro próximo de um valor nulo que não existe e o ponteiro aux da mesma função está sendo ordenado em seu membro apontado ponteiro próximo a apontar para algo que ele não pode por o valor de aux ser nulo e seus membros apontados não existirem. Para resolver isso coloca-se uma variável contadora de elementos da lista com número de matrícula menor do que o que está sendo inserido. Se o resultado do contador for 0 aponta-se o início da lista para o novo elemento e o ponteiro próximo do novo elemento para a lista atual aonde já estarão os outros elementos consecutivos.

 

A função imprime fica para sempre imprimindo somente a primeira matrícula repetidas vezes por que não foi colocado a linha de código que faz o ponteiro p avançar para o próximo da lista que é:

p=p->prox;

Nenhuma função da biblioteca string é usada. A linha que a adiciona pode ser removida.

 

O mesmo programa porém com essas modificações que eu disse fica:

#include <stdio.h>

struct aluno {
int matricula ;
char nome [ 100 ];
float media ;
};
typedef struct aluno Aluno ;
struct no {
Aluno * dados ;
struct no * prox ;
};
typedef struct no No;
No* ins_ordenado ( No* l , int mat , char* nome , float nota ){
int contadora;

Aluno * Al=( Aluno *)malloc
( sizeof( Aluno ));
No* novo =( No*)malloc( sizeof
( No));
int i = 0 ;
Al-> matricula = mat ;
while ( nome[i]!= '\0' ){
Al-> nome[i]= nome[i];
i ++;
}
Al-> nome[i]= NULL;
Al-> media = nota;
novo -> dados = Al;
No* p = l ;
No* aux = NULL;
if( l ==NULL){
novo -> prox= l ;
return novo ;
}
contadora=0;
while ( p != NULL&&p -> dados -> matricula < Al-> matricula ){
aux = p ;
p = p -> prox;
contadora++;
}
if(contadora>0){
novo -> prox= aux -> prox;
aux -> prox= novo;
}
else{
novo->prox=l;
l=novo;
return l;
}
if( p ==NULL){
novo -> prox= NULL;
}
return l ;
}
void imprime ( No* l ){
No* p ;
printf ( "turma 1:\n" );
for ( p = l ; p != NULL; p -> prox){
printf ( "Matricula: %d\t Nome: %s Nota:%f\n" , p -> dados -> matricula , p -> dados -> nome, p -> dados -> media );
p=p->prox;
}
printf ( "\n" );
}
int vazia ( No* l ){
return( l ==NULL);
}
int main (){
No* l1;
l1=NULL;
l1 = ins_ordenado ( l1 , 1 , "Maria" , 5 );
ins_ordenado ( l1 , 2 , "Joao" , 10 );
ins_ordenado ( l1 , 3 , "Jose" , 6 );
ins_ordenado ( l1 , 5 , "Joaquim" , 7 );
ins_ordenado ( l1 , 4 , "Manoel" , 8 );
l1=ins_ordenado ( l1 , 0 , "Felipe" , 9 );

printf( "vazia? %d" , vazia ( l1 ));
imprime(l1);
system("pause");
return 0 ;
}

 

Compartilhar este post


Link para o post
Compartilhar em outros sites
Visitante
Este tópico está impedido de receber novos posts.

  • Conteúdo Similar

    • Por jeredy
      Tenho um trabalho da faculdade e não consigo fazer rodar o programa corretamente.
      Quando eu coloco o cpf, na hora de imprimir sai um número aleatório. Creio que possa ser por falta de memória pois se coloco um número menor ele sai certo, porém não consigo adicionar memória em cpf.
       
      Obs: ainda não fiz a parte dos menores e da medial do grupo e a parte de imprimir em tabela pois não consegui fazer funcionar nem um básico mas se alguém souber essa parte também e puder me ajudar agradeço!!
       
      #include <stdio.h> #include <stdlib.h> main(){ struct funcionarios{ int *cpf; char nome[30]; int nascimento; float salario; }; int aux=0; //para testar se for 0 antes de armazenar o cpf struct funcionarios *func; int qtdLeitura=0, i=0, cont=0; func = ((struct funcionarios *) (malloc(sizeof(struct funcionarios) * 1))); while(1){ printf("Digite o cpf %d: ", i+1); scanf("%d", &aux); if(aux!= 0){ func.cpf = aux; fflush(stdin); } else{ break; } if(func != NULL){ qtdLeitura++; func = ((struct funcionarios *) realloc(func, sizeof(struct funcionarios) *(qtdLeitura+1))); } printf("Digite o nome %d: ", i+1); scanf("%s", func.nome); printf("Digite o nascimento %d: ",i+1); scanf("%d", &func.nascimento); printf("Digite o salario %d: ",i+1); scanf("%f", &func.salario); cont++; i++; } printf("\n\n"); for(i=0;i<cont;i++){ printf("Cpf %d:%d \n",i+1, func.cpf); printf("Nome %d: %s\n",i+1, func.nome); printf("Nascimento %d: %d\n",i+1, func.nascimento); printf("Salario %d: %.2f\n",i+1, func.salario); } }
       

    • Por juliaKrunker
      1- O comando typedef pode ser utilizado para criar novos comandos, ou simplesmente novas formas de escrever
      determinados comandos em linguagem C. Por exemplo, toda vez que você quiser criar uma variável do tipo struct
      declarado acima, terá que escrever o nome completo do tipo, isto é struct lista. Usando o comando typedef, defina um
      tipo alternativo, chamado Lista, que possa ser usado em lugar de struct lista.

      2-  Usando o tipo Lista que você criou na questão 3, declare uma variável chamada myList que possa ser utilizada para
      construir uma lista encadeada.
       
      3- (0,5) Usando o tipo Lista que você criou na questão 3, declare uma variável chamada novo que possa ser utilizada para criar
      um novo elemento para a lista declarada na questão 4.

      4- Escreva uma linha de código que aloque espaço na memória para a variável novo declarada na questão 5, de forma
      que a variável possa ser utilizada para inserir um novo elemento na lista myList declarada na questão 4.

      5 -Considerando a variável myList declarada na questão 4 e a variável novo declarada na questão 5 e alocada na questão
      6, atribua os valores 1 para o atributo id e 9.1 para o atributo valor e insira-a na lista myList.
       
      6- O trecho de código apresentado a seguir, refere-se a uma função que receberá como parâmetro um ponteiro para
      uma lista do tipo Lista e deverá calcular e retornar a média dos valores existentes na lista. Escreva o corpo da função.

    • Por Ak_Ray
      Olá pessoal, estou com um problema relativamente simples! mas sou novo em banco de dados e php então não consegui resolver. Estou construindo um sistema de registro e login há um certo tempo, meu professor ainda não ensinou e não ensina muito bem então decidi aprender sozinho por tutoriais na internet ._. então achei um tutorial legal, segui todos os passos e está tudo funcionando! porém, agora quero exibir os dados registrados, porém não sei como fazer isso, quero exibir em específico o nome do usuário. Lembrando que sou novo nesse assunto então desconsiderem minha maneira de programar kkk
       
      ================================================================================================================================
      Código php:
      <?php
      class Usuario
      {
          private $pdo;
          public $msgErro = "";
          public function conectar($nome, $host, $usuario, $senha)
          {
              global $pdo;
              global $msgErro;
              try {
              $pdo = new PDO("mysql:dbname=".$nome.";host=".$host,$usuario,$senha);    
              } catch (PDOException $e) {
                  $msgErro = $e->getMessage(); 
              }
          return $conectar;    
          }
          public function cadastrar($nome, $telefone, $email, $senha)
          {
              global $pdo;
              //verificar se já existe email cadastrado 
              $sql = $pdo->prepare("SELECT id_usuario from usuarios where email = :e");
              $sql->bindValue(":e",$email);
              $sql->execute();
              if($sql->rowCount() > 0)
              {
                  return false; // ja esta cadastrado
              }
              else 
              {
                   //caso não, cadastrar 
                   $sql = $pdo->prepare("INSERT INTO usuarios (nome,telefone,email,senha) VALUES (:n, :t, :e, :s)");
                   $sql->bindValue(":n",$nome);
                   $sql->bindValue(":t",$telefone);
                   $sql->bindValue(":e",$email);
                   $sql->bindValue(":s",md5($senha));
                   $sql->execute();
                   return true; 
              }     
              
          }
          public function logar($email, $senha)
          {
              global $pdo;
              //verificar se  o email e senha estao cadastrados, se sim  
              $sql = $pdo->prepare("SELECT id_usuario from usuarios where email = :e and senha = :s");
              $sql->bindValue(":e",$email);
              $sql->bindValue(":s",md5($senha));
              $sql->execute();
              if($sql->rowCount() > 0)
              {
                 //entrar no sistema (sessao)
                 $dado = $sql->fetch();
                 session_start();
                 $_SESSION['id_usuario'] = $dado['id_usuario'];
                 return true; //logado com sucesso 
              }
              else
              {
                 return false;//nao foi possível logar
              }
              //entrar no sistema (sessao)
          }
      }
      ?>
       
      ================================================================================================================================
      Código html:
      <!-- verificação se está logado -->
      <?php 
      session_start(); 
      if(!isset($_SESSION['id_usuario']))

      header("location: index.php"); 
      exit; 
      }
      else{    
          include ('CLASSES/usuarios.php');
          require_once 'CLASSES/usuarios.php';
          $consulta = "SELECT nome from usuarios"; //aqui estava tentando puxar os dados por um tutorial aleaório

      }
      ?> 
      <html lang="pt-br">
      <head>
      <meta charset="utf-8">
      <link rel="stylesheet" href="CSS/estilouser.css" type="text/css" media="screen">
      <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
      <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet"> 
      <title> Ak_Ray Projects </title>
      </head> <body bgcolor="#B3D1F7">

      <div class="navbar">
      <a href="#home">Meu</a>
      <a href="#news">Projetos</a>
      <a href="#newss">Novidades</a>
      <a href="sair.php" style="position: relative;left:1020px;">Sair</a>
      <!--<a href="sair.php">Sair</a>-->
      </div>
      <div class="branco"> 
      <h2>
        <center>
         <font color="#20A1C6">
          Criação e Desenvolvimento de Jogos<br>Ak_Ray
         </font>
        </center>
       </h2>
      <div class="titlee">
      <strong>The Amazing word of Bimo</strong>
      <div class="contt">
      <center><img src="IMG/FOTOJOGO.png" width="150" style="border-radius: 20px;"></center>
      <a href=\"bimo.netlify.com\"><img class="animacao" src="IMG/button.png" width="40"></a>
      </div>
      </div><br>
      The Amazing Word of Bimo foi um Jogo criado em 2019, inspirado na franquia de jogos de <strong>Super Mario World.</strong>
      O jogo está em versão de desenvolvimento e está sendo produzido e alterado
      constantemente. 
      </div>
      <?php  echo con;  ?> // exibindo só de teste

      </body></html>
       
      ================================================================================================================================
      Obs caso precisem: 
      nome do banco de dados:  projeto_login
      host: localhost
      usuario: root
      senha: ""
      tabela criada: usuarios
      tutoriais assistidos: 
       
    • Por alexkbw
      ola, preciso de ajuda
      estou aprendendo C++ 
      e nao consigo criar uma lista encadeada que armazene palavras
      segue o codigo:
       
      // listaEncadeada.cpp : Este arquivo contém a função 'main'. A execução do programa começa e termina ali. #include "pch.h" #include "conio.h" #include "string" #include<iostream> using namespace std; struct lista { char c; int n; struct lista*p; }; struct lista * inserirn(char,int); struct lista * prim; void inserir() { char c; int n; printf("\ninforme uma cor :"); scanf_s("%s", &c); printf("\ninforme um numero:"); scanf_s("%d", &n); inserirn(c,n); } struct lista * inserirn(char c,int n) { struct lista *novo, *aux; novo = (struct lista*)malloc(sizeof(struct lista)); if (novo!=NULL)//caso nao aja memoria { novo->n= n; novo->c = c; novo->p = NULL; if (prim==NULL) { prim = novo; } else { aux = prim; while (aux->p != NULL) { aux = aux->p; } aux->p = novo; } } return novo; } int main() { prim = NULL; inserir(); inserir(); inserir(); _getch(); }  
×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.