Autor Tópico: Problemas com Structs e alocacao dinamica em C  (Lida 2923 vezes)

Offline ccleiison

  • Usuário Ubuntu
  • *
  • Mensagens: 2
    • Ver perfil
Problemas com Structs e alocacao dinamica em C
« Online: 04 de Maio de 2010, 14:16 »
Bom pessoal estou com um problema em uma struct aki, esta acusando tipos incompativeis na atribuicao, mas ambas as variaveis  são do tipo char..

segue o fontes para darem uma olhada, o fonte nem compila.

Estrutura.h
Citar
#ifndef _ESTRUTURA_H
#define _ESTRUTURA_H

#define TAM_CHAR 50

struct evento{
       char nome[TAM_CHAR];
       char data[10];
       char hora[15];
       char local[TAM_CHAR];
       struct evento *prox;
       struct evento *ant;
};

typedef struct evento EVENTO;

void insere_evento(EVENTO *evento,EVENTO *inicio);
void insere_evento_arquivo(EVENTO *evento,EVENTO *inicio);
void insere_evento_tela(EVENTO *evento,EVENTO *inicio,char nome[TAM_CHAR], char data[10], char hora[15], char local[TAM_CHAR]);
void altera_evento(char nome[TAM_CHAR]); //- se altera mês deve trocar a posição na lista de meses
void remove_evento(char nome[TAM_CHAR]);
void consulta_evento_nome(char nome[TAM_CHAR]); // Saida: datadia, datames, dataano, horário, local);
void consulta_evento_data(int data_dia,int data_mes,int data_ano); // S: lista_eventos exibir em ordem cronológica de data
void consulta_eventos_mes(int data_mes); // S: lista_eventos);
void consulta_eventos(); //S: todos lista_eventos)- em ordem de data ou alfabética pelo nome do evento, ou por outro critério de ordenação à escolha
void consulta_eventos_recentes(); //S:cinco últimos eventos manipulados:evento inserido ou alterado (usar fila circular)
void menu();
void chama_funcao(int opcao,EVENTO *evento,EVENTO *inicio);

#endif

Main.c
Citar
#include <stdio.h>
#include <stdlib.h>
#include "estrutura.h"

EVENTO *evento;
EVENTO *inicio;
   
int main(){   
    int opcao = 1;
   
    inicio=NULL;
    while(opcao !=0){         
          menu();
          scanf("%d",&opcao);
          chama_funcao(opcao,evento,inicio);
    }       
    printf("\n\n");
    system("PAUSE");   
    return 0;
}


Estrutura.c


Citar
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "estrutura.h"

void insere_evento(EVENTO *evento,EVENTO *inicio){
     int opcao=1;
     char nome[TAM_CHAR],data[10],hora[15],local[TAM_CHAR];
     
     printf("\n1 - Arquivo\n2 - Tela\n0 - Retorna\n");
     scanf("%d",&opcao);
     switch(opcao){
           case 0: break;       
           case 1: insere_evento_arquivo(evento,inicio);
                   break;                 
           case 2: printf("\nNome do evento: ");
                   scanf("%s",&nome);
                   while(evento->prox != NULL){
                         if(strcmp(evento->nome,nome)){
                            printf("\nEvento ja esta cadastrado para o dia %s ",evento->data);                           
                            return;
                         }         
                         evento = evento->prox;
                   }
                   printf("\nData: ");
                   scanf("%s",&data);
                   printf("\nHora: ");
                   scanf("%s",&hora);
                   printf("\nLocal: ");
                   scanf("%s",&local);
                   insere_evento_tela(evento,inicio,nome,data,hora,local);
                   system("pause");
                   break;                 
           default: printf("\nOpcao incorreta!\n");
                    system("pause");
                    break;
     }           
}
/* -------------------------------------------------------------------------- */
void insere_evento_arquivo(EVENTO *evento,EVENTO *inicio){
     FILE *arq;
     char arqStr[50],linha[TAM_CHAR];
     int i = 0, duplicados = 0;
     EVENTO *atual = inicio;
     EVENTO *aux = NULL;
     
     fflush(stdin);
     printf("Digite o nome do arquivo:\n");
     //scanf("%s", arqStr);
     
     if ((arq = fopen("agenda.txt" /*arqStr*/,"r")) == NULL){
       fprintf(stderr, "Problema encontrado na abertura do arquivo!");
       exit(-1);
     }
       
     while(!feof(arq)){         
           evento=(EVENTO*)malloc(sizeof(EVENTO));
           evento->ant=NULL;
           evento->prox=NULL;
           atual = inicio;
           if(inicio == NULL){
              i++;
              fgets(evento->nome,TAM_CHAR,arq);
              fgets(evento->data,14,arq);
              fgets(evento->hora,15,arq);
              fgets(evento->local,TAM_CHAR,arq);         
              /*printf("\n==================================");
              printf("\n%d",i);
              printf("\nlinha %d: %s", i, evento->nome);
              printf("\nlinha %d: %s", i, evento->data);
              printf("\nlinha %d: %s", i, evento->hora);
              printf("\nlinha %d: %s", i, evento->local);
              printf("\n==================================");*/
             
              inicio = evento;
           }
           else{
                //move para o ultimo registro da lista
                while(atual->prox != NULL){
                      atual = atual->prox;
                                             
                }
                i++;
                fgets(evento->nome,TAM_CHAR,arq);
                fgets(evento->data,14,arq);
                fgets(evento->hora,15,arq);
                fgets(evento->local,TAM_CHAR,arq);         
                /*printf("\n==================================");
                printf("\n%d",i);
                printf("\nlinha %d: %s", i, evento->nome);
                printf("\nlinha %d: %s", i, evento->data);
                printf("\nlinha %d: %s", i, evento->hora);
                printf("\nlinha %d: %s", i, evento->local);
                printf("\n==================================");*/
                evento->ant = atual;
                atual->prox = evento;                     
           }

     }
     fclose(arq);
     printf("\nTotal de eventos importados: %d\n", i);
     printf("\nTotal de eventos duplicados e nao importados: %d\n", duplicados);
     system("pause");
     return;
}
/* -------------------------------------------------------------------------- */
void insere_evento_tela(EVENTO *evento,EVENTO *inicio,char nome[TAM_CHAR], char data[10], char hora[15], char local[TAM_CHAR]){
     EVENTO *atual = inicio;
               
     evento=(EVENTO*)malloc(sizeof(EVENTO));
     evento->ant=NULL;
     evento->prox=NULL;
     atual = inicio;
     if(inicio == NULL){
        evento->nome = nome;
        evento->data = data;
        evento->hora = hora;
        evento->local = local;
        inicio = evento;
       }
     else{
          //move para o ultimo registro da lista
          while(atual->prox != NULL){
                atual = atual->prox;
                                       
          }
          evento->nome = nome;
          evento->data = data;
          evento->hora = hora;
          evento->local = local;       
          evento->ant = atual;
          atual->prox = evento;                   
     }
     printf("\nTotal de eventos duplicados e nao importados: %d\n");
     system("pause");
     return;
}
/* -------------------------------------------------------------------------- */
void menu(){
     system("cls");
     printf("========================== Agenda Cultural ==========================\n");
     printf("\n1 - Insere novo evento");
     printf("\n2 - Altera evento");
     printf("\n3 - Exclui evento");
     printf("\n4 - Consulta evento por nome");
     printf("\n5 - Consulta evento por data");
     printf("\n6 - Consulta evento por mes");
     printf("\n7 - Lista todos os eventos");
     printf("\n8 - Lista 5 ultimos eventos. (cadastrados/alterados)");
     printf("\n0 - SAIR\n");
}
/* -------------------------------------------------------------------------- */
void chama_funcao(int opcao,EVENTO *evento,EVENTO *inicio){
     switch(opcao){
           case 0: break;       
           case 1: insere_evento(evento,inicio);
                   break;                 
           case 2:
                   break;                 
           case 3:
                   break;                 
           case 4:
                   break;                 
           case 5:
                   break;                 
           case 6:
                   break;                 
           case 7:
                   break;                 
           case 8:
                   break;
           default: printf("\nOpcao incorreta!\n");
                    system("pause");
                    break;
     }
 }   
/* -------------------------------------------------------------------------- */

print do erro:

Offline fpissarra

  • Usuário Ubuntu
  • *
  • Mensagens: 246
    • Ver perfil
    • Lost in the e-Jungle
Re: Problemas com Structs e alocacao dinamica em C
« Resposta #1 Online: 04 de Maio de 2010, 23:47 »
Isso acontece porque vocẽ não pode copiar blocos com o operador de assinalamento (=):

Código: [Selecionar]
void insere_evento_tela(EVENTO *evento,EVENTO *inicio,char nome[TAM_CHAR], char data[10], char hora[15], char local[TAM_CHAR]){
     EVENTO *atual = inicio;
              
     evento=(EVENTO*)malloc(sizeof(EVENTO));
     evento->ant=NULL;
     evento->prox=NULL;
     atual = inicio;
     if(inicio == NULL){
        /* As 5 linhas abaixo estão erradas */
        evento->nome = nome;
        evento->data = data;
        evento->hora = hora;
        evento->local = local;
        inicio = evento;
       }
     else{
          //move para o ultimo registro da lista
          while(atual->prox != NULL){
                atual = atual->prox;
                                      
          }

           /* As 4 linhas abaixo estão erradas */
          evento->nome = nome;
          evento->data = data;
          evento->hora = hora;
          evento->local = local;
          evento->ant = atual;
          atual->prox = evento;                  
     }
     printf("\nTotal de eventos duplicados e nao importados: %d\n");
     system("pause");
     return;

Use a função strcpy() para copiar. Assim:

Código: [Selecionar]
strcpy(evento->nome, nome);
Outra coisa... Dentro do if vc colocou:

Código: [Selecionar]
       inicio = evento;
Só que essa variável é declarada como um ponteiro passado como parâmetro para a função e, portanto, é local. O mesmo acontece com evento. Faça o teste:

Código: [Selecionar]
int main(int argc, char **argv)
{
  int x = 1;

  f(&x);

  printf("%d\n", x);

  return 0;
}

void f(int *a)
{
  int *m = (int *)malloc(sizeof(int));
  *m = 10;
  a = m;
}

Você obterá o resultado "1", e não "10".
« Última modificação: 04 de Maio de 2010, 23:51 por fpissarra »

Offline ccleiison

  • Usuário Ubuntu
  • *
  • Mensagens: 2
    • Ver perfil
Re: Problemas com Structs e alocacao dinamica em C
« Resposta #2 Online: 06 de Maio de 2010, 00:55 »
e mais um erro novo, depois de muito mudar e melhorar o programa...

na funcao "insere_novo", em qualuqer tentativa de utilizacao da struct lista o programa trava a execucao.... n sei masi oq fzer =/ esse trabalho tenho que entregar nesta quinta a noite =/

segue os fontes...

estrutura.h
Código: [Selecionar]
#ifndef _ESTRUTURA_
#define _ESTRUTURA_H

#define TAM_CHAR 50

struct evento{
       char nome[TAM_CHAR];
       char data[10];
       char hora[15];
       char local[TAM_CHAR];
       struct evento *prox;
       struct evento *ant;
};

typedef struct evento EVENTO;

//Funcoes ok
void insere_evento(EVENTO **evento,EVENTO **inicio,EVENTO *meses[12]);
void insere_evento_arquivo(EVENTO **evento,EVENTO **inicio,EVENTO *meses[12]);
void menu(); //exibe o menu de opcoes na tela
void mostra_lista(EVENTO *meses[12]); //Imprime a lista na tela
int consulta_dado(EVENTO *lista,char nome[TAM_CHAR]); //verifica se um determinado elemento ja esta na lista
int verifica_vazio(EVENTO* lista);//Verifica se a lista esta vazia.(1 = Vazio - 0 = Com dados)

//funcao insere_novo so insere no final ate o momento
void insere_novo(EVENTO *meses[12], char nome[TAM_CHAR], char data[10], char hora[15], char local[TAM_CHAR]); //Insere um novo elemento na lista ordenado por data
//Fim funcoes ok


//fubncoes para implementar
void altera_evento(char nome[TAM_CHAR]); //- se altera mês deve trocar a posição na lista de meses
void remove_evento(char nome[TAM_CHAR]);
void consulta_evento_nome(char nome[TAM_CHAR]); // Saida: datadia, datames, dataano, horário, local);
void consulta_evento_data(int data_dia,int data_mes,int data_ano); // S: lista_eventos exibir em ordem cronológica de data
void consulta_eventos_mes(int data_mes); // S: lista_eventos);
void consulta_eventos(); //S: todos lista_eventos)- em ordem de data ou alfabética pelo nome do evento, ou por outro critério de ordenação à escolha
void consulta_eventos_recentes(); //S:cinco últimos eventos manipulados:evento inserido ou alterado (usar fila circular)


#endif


main.c
Código: [Selecionar]
#include <stdio.h>
#include <stdlib.h>
#include "estrutura.h"
   
int main(){   
    EVENTO *evento = NULL;
    EVENTO *inicio = NULL;
    EVENTO *meses[12];
    int opcao=1,i=0;
   
   
   
    for(i=0;i<12;i++) meses[i] = NULL;             
    while(opcao !=0){         
         menu();
         scanf("%d",&opcao);
         //chama_funcao(opcao,&evento,&inicio,&meses);
         switch(opcao){
               case 0: break;       
               case 1: insere_evento(&evento,&inicio,meses);
                       system("pause");
                       break;                 
               case 2:
                       system("pause");
                       break;                 
               case 3:
                       system("pause");
                       break;                 
               case 4:
                       system("pause");
                       break;                 
               case 5:
                       system("pause");
                       break;                 
               case 6:
                       system("pause");
                       break;                 
               case 7:
                       system("pause");
                       break;                 
               case 8:
                       system("pause");
                       break;
               default: printf("\nOpcao incorreta!\n");
                        system("pause");
                        break;
         }
         mostra_lista(meses);
         //nao esta inseridno masi eventos
    }       
    printf("\n\n");
    system("PAUSE");
    return 0;
}


estrutura.c
Código: [Selecionar]
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "estrutura.h"

void insere_evento(EVENTO **evento,EVENTO **inicio,EVENTO *meses[12]){   
     int opcao=1;
     char nome[TAM_CHAR],data[10],hora[15],local[TAM_CHAR];
     printf("\n1 - Arquivo\n2 - Tela\n0 - Retorna\n");
     scanf("%d",&opcao);
     switch(opcao){
           case 0: break;       
           case 1: insere_evento_arquivo(&*evento,&*inicio,meses);
                   break;                 
           case 2: printf("\nNome do evento: ");
                   scanf("%s",&nome);                   
                   if((verifica_vazio(*evento)) == 0){
                      if((consulta_dado(*evento,nome)) == 0){
                         printf("\nEvento ja esta cadastrado!\n");   
                         return;
                         }
                   }
                   printf("\nData: ");
                   scanf("%s",&data);
                   printf("\nHora: ");
                   scanf("%s",&hora);
                   printf("\nLocal: ");
                   scanf("%s",&local);
                   //aquiii
                   //*evento = insere_novo(*evento,meses,nome,data,hora,local);
                   if((verifica_vazio(*inicio) != 0)){
                       *inicio = *evento;       
                   }
                   break;                 
           default: printf("\nOpcao incorreta!\n");
                    break;
     }   
}
/* -------------------------------------------------------------------------- */
void insere_evento_arquivo(EVENTO **evento,EVENTO **inicio,EVENTO *meses[12]){
     FILE *arq;     
     char arqStr[50],linha[TAM_CHAR];
     char nome[TAM_CHAR],data[10],hora[15],local[TAM_CHAR];
     int i = 0, duplicados = 0,aux=0,mes=0;
       
     fflush(stdin);
     printf("Digite o nome do arquivo:\n");
     scanf("%s", arqStr);
     
     if ((arq = fopen(arqStr,"r")) == NULL){
        fprintf(stderr, "Problema encontrado na abertura do arquivo!\n");
        system("pause");
        exit(-1);
     }
     while(!feof(arq)){
           i++;
           fgets(nome,TAM_CHAR,arq);
           fgets(data,14,arq);
           fgets(hora,15,arq);
           fgets(local,TAM_CHAR,arq);                           
           
           sscanf(data,"%d/%d/%d",&aux,&mes,&aux);
           /*if((verifica_vazio(meses[mes])) == 0){
              if((consulta_dado(meses[mes],nome)) == 0){ 
                 duplicados ++;
                 i--;
                 continue;
                 }
           } */
           insere_novo(meses,nome,data,hora,local);
     }
     fclose(arq);
     printf("\nTotal de eventos importados: %d\n", i);
     printf("\nTotal de eventos duplicados e nao importados: %d\n", duplicados);
}
/* -------------------------------------------------------------------------- */
void menu(){
     system("cls");
     printf("========================== Agenda Cultural ==========================\n");
     printf("\n1 - Insere novo evento");
     printf("\n2 - Altera evento");
     printf("\n3 - Exclui evento");
     printf("\n4 - Consulta evento por nome");
     printf("\n5 - Consulta evento por data");
     printf("\n6 - Consulta evento por mes");
     printf("\n7 - Lista todos os eventos");
     printf("\n8 - Lista 5 ultimos eventos. (cadastrados/alterados)");
     printf("\n0 - SAIR\n");
}
/* -------------------------------------------------------------------------- */
void insere_novo(EVENTO *meses[12], char nome[TAM_CHAR], char data[10], char hora[15], char local[TAM_CHAR]){
        EVENTO *novo = (EVENTO*) malloc (sizeof(EVENTO));
        EVENTO *lista = NULL;
        int dia=0,mes=0,ano=0;
        strcpy(novo->nome,nome);
        strcpy(novo->data,data);
        strcpy(novo->hora,hora);
        strcpy(novo->local,local);
       
        sscanf(data,"%d/%d/%d",&dia,&mes,&ano);
        *lista = *meses[mes];
        //move para o ultimo registro da lista
        printf("\ninsere\n");
        if((verifica_vazio(lista)) == 0){ 
                                   printf("\ndentro\n");     
            while(lista->prox != NULL){
                              printf("\ndentro while\n");
                  lista = lista->prox;
                  printf("\n- SAIR\n");
            }
            printf("\n1 - SAIR\n");
            lista->prox = novo;
            novo->prox = NULL;
            novo->ant = lista;
        }
        else{
             novo->prox = NULL;
             novo->ant = NULL;             
             meses[mes-1] = novo;;
        }
}
/* -------------------------------------------------------------------------- */
void mostra_lista(EVENTO *meses[12]){
     EVENTO*mostra;
     int i=0;
     /*for(i=0;i<12;i++) printf("\nmeses[%d] = %d",i,meses[i]);
     system("pause");*/
     for(i=0;i<12;i++){
        //for(mostra = meses[i]; mostra->prox != NULL; mostra = mostra->prox){
        mostra = meses[i];
        if((verifica_vazio(mostra)) == 0){
            printf("\nmeses[%d] = %d",meses[i],mostra->prox);             
            for(mostra = meses[i]; mostra->prox != NULL; mostra = mostra->prox){
                printf("\n====================\n");
                printf("Evento = %s\n", mostra->nome);
                printf("Data = %s\n", mostra->data);
                printf("Hora = %s\n", mostra->hora);
                printf("Local = %s\n", mostra->local);
                printf("\n====================\n");
            }
            system("pause");
        }
        else
         printf("\nNao existem eventos para o mes %d!\n", i+1);
     }
}
/* -------------------------------------------------------------------------- */
int verifica_vazio(EVENTO* lista){
    return (lista == NULL);
}
/* -------------------------------------------------------------------------- */
int consulta_dado(EVENTO* lista,char nome[TAM_CHAR]){   
    EVENTO*mostra; 
    for(mostra = lista; mostra != NULL; mostra = mostra->prox){
        if(strcmp(lista->nome,nome) == 0){                           
           return 0;
        }         
        lista = lista->prox;
    }
    return 1;
}
/* -------------------------------------------------------------------------- */



Offline fpissarra

  • Usuário Ubuntu
  • *
  • Mensagens: 246
    • Ver perfil
    • Lost in the e-Jungle
Re: Problemas com Structs e alocacao dinamica em C
« Resposta #3 Online: 08 de Maio de 2010, 16:21 »
Em "insere_evento" você tem certeza que quer fazer isso:

Código: [Selecionar]
switch(opcao){
           case 0: break;       
           case 1: insere_evento_arquivo(&*evento,&*inicio,meses);
                   break;           

'&*evento' pode ser tranquilamente substituido somente por 'evento' (sem as aspas simples). Mas existem outras falhas...

Use o gdb para debugar a aplicação...

Offline ccleiison

  • Usuário Ubuntu
  • *
  • Mensagens: 2
    • Ver perfil
Re: Problemas com Structs e alocacao dinamica em C
« Resposta #4 Online: 09 de Maio de 2010, 16:55 »
pode fechar ja FIZ TUDO SOZIN GRATO PELA "AJUDA" ???

Offline clcampos

  • Administrador
  • Usuário Ubuntu
  • *****
  • Mensagens: 10.790
  • .:: User Linux #439596 ::.
    • Ver perfil
Re: Problemas com Structs e alocacao dinamica em C
« Resposta #5 Online: 09 de Maio de 2010, 17:12 »
Tópico trancado. Uso de caixa alta.
Cristiano/Timóteo - MG
.: Como Fazer Perguntas de Forma Inteligente :.                
Com dúvida? pesquise!