1. Este site usa cookies. Ao continuar a usar este site está a concordar com o nosso uso de cookies. Saber Mais.

Como os ponteiros lixaram-me um bom programa (c)

Discussão em 'Programação' iniciada por S|N, 22 de Abril de 2005. (Respostas: 16; Visualizações: 1205)

  1. S|N

    S|N Power Member

    Ola, eu fiz um programa que funcionava perfeitamente mas quando apliquei-lhe ponteiros (invés de variáveis globais) ele não só deixou de funcionar como dá-me +50 erros que não entendo. O programa é simples e está estruturalmente correcto.
    Alguem pode corrigir-me este programa?

    Inunciado:

    12. Pretende-se um programa que faça a gestão de inscrições de alunos num determinado turno prático. Para cada aluno existe o seu número (um número inteiro) e o nome (um cadeia de caracteres com, no máximo, 60 caracteres), sabendo-se que a capacidade máxima é 30 alunos. As operações a implementar são as seguintes:

    * inscrição de um aluno
    * listagem dos alunos do turno, por ordem alfabética
    * remoção de um aluno, dado o seu número

    Altere o programa anterior de modo a que:

    1. o programa carregue a informação relativa ao turno a partir do ficheiro de texto turno.txt .
    2. no final, o programa armaze os dados sobre o turno no mesmo ficheiro que utilizou para ler, mas com os dados ordenados por ordem alfabética.


    Código:

    #include <stdio.h>
    #include <string.h>
    #define MAX_ALUNOS 30
    #define MAX_NOME 60

    /*Estruturas de dados*/
    /*char nome[MAX_ALUNOS][MAX_NOME]; para dentro do main*/
    /*int numero[Max_Alunos]; para dentro do main*/
    /*int nalunos; para dentro do main*/

    /*Protótipos*/
    void op_inscrever_aluno(int *nalunos, int numero[], char nome[][MAX_ALUNOS]);
    void op_listar_alunos(char nome[][MAX_ALUNOS])
    void op_remover_aluno(void);
    int remover(int aluno);
    void shift_esquerda_alunos(int posicao);
    void carregar_ficheiro(void);
    void guardar_ficheiro(void);

    /*---------------------------------------------------*/
    /* Inscreve um aluno, fornecidos o nome e o numero */
    /*---------------------------------------------------*/
    void inscrever_aluno(int *nalunos, int numero[], char nome[][MAX_ALUNOS])
    {
    fflush(stdin);
    printf("Qual o nome do aluno?");
    scanf("%['\n']",nome[*nalunos]);
    scanf("%d",&numero[*nalunos]);
    (*nalunos)++;
    }

    /*-------------------*/
    /* Lista os alunos */
    /*-------------------*/
    void op_listar_alunos(char nome[][MAX_ALUNOS])
    {
    int indice;
    for (indice=0; indice<MAX_ALUNOS; indice++)
    {
    printf("%d%s\n",indice+1,nome[indice]);
    }
    }

    /*----------------------------------------------------------------------------*/
    /* Pede o número do aluno e remove o aluno, reorganizando a lista de alunos */
    /*----------------------------------------------------------------------------*/
    void op_remover_aluno(void)
    {
    int num_aluno;
    printf("\n numero aluno a remover = ");
    scanf("%d", &num_aluno);

    if (remover(num_aluno, *nalunos, numero[])==1)
    printf("\n ALUNO REMOVIDO COM SUCESSO");
    else
    printf("\n ALUNO A REMOVER NAO EXISTE");
    }

    /*----------------------------------------------------------------------------*/
    /* Remove um aluno dado o seu número. Retorna 1 se removeu, 0 caso contrário */
    /*----------------------------------------------------------------------------*/
    int remover(int num_aluno, int *nalunos, int numero[])
    {
    int indice;

    /* pesquisa */
    indice=0;
    while ((indice<*nalunos) && (num_aluno != numero[indice]))
    i++;

    /* remove se encontrou */
    if (aluno == numero[indice])
    {
    shift_esquerda_alunos(indice);
    return 1;
    }
    else
    return 0;
    }

    /*----------------------------------------------------------------------------*/
    /* Desloca os registos dos alunos para a esquerda esmagando a posicao dada */
    /*----------------------------------------------------------------------------*/
    void shift_esquerda_alunos(int posicao int *nalunos int numero[],name[][MAX_ALUNOS])
    {
    int indice;

    if (*nalunos==0)
    return;

    for (indice=posicao; indice<nalunos-1; indice++)
    {
    numero[indice] = numero[indice+1];
    strcpy(name[indice],name[indice+1]);
    }

    nalunos--;
    }

    void carregar_ficheiro(void)
    {
    FILE *fich;
    fich=fopen("turno.txt","r");
    int indice;
    while(!feof(fich))
    {
    for (indice=0;(indice<MAX_ALUNOS);indice++)
    {
    fscanf("%d",&numero[indice];
    fscanf("%['\n']",name[indice];
    }
    }
    fclose(fich);
    }

    void guardar_ficheiro(int *nalunos int numero[])
    {
    FILE *fich;
    int indice;
    fich=fopen("turno.txt","a");
    for(indice=0; indice<(*nalunos); indice++)
    {
    fprintf(fich,"%d ",numero[indice];
    fprintf(fich,"%s\n",name[indice];
    }
    }


    void main(void)
    {
    int nalunos;
    int numero[MAX_ALUNOS];
    char nome[MAX_NOME][MAX_ALUNOS];
    int opcao;
    nalunos=0;
    carregar_ficheiro();
    do
    {
    menu();
    scanf("%d",&opcao);
    switch (opcao)
    {
    case 1: op_inscrever_aluno(&nalunos,numero,nome); break;
    case 2: op_remover_aluno(); break;
    case 3: op_listar_alunos(nalunos,numero,nome); break;
    }
    while(opcao!=0);
    guardar_ficheiro();
    }
    }
     
    Última edição: 22 de Abril de 2005
  2. hasta.g5

    hasta.g5 I quit My Job for Folding

    Lamento mas não percebo bolha de ponteiros... Só quando não tiver outro remédio é que vou aprender.. :D
    Mas se queres uma sugestão, nunca se põe printf's nem scanf's a não ser no main. Se é um trabalho para uma disciplina aconselhava-te a mudar porque, muito provavelmente, o prof toma isso em conta...
     
  3. HiGhVoIcE

    HiGhVoIcE Power Member

    primeiro de tudo muda a cor que nao se ve nada...

    depois...

    void inscrever_aluno(int *nalunos, int numero[], char nome[][MAX_ALUNOS])
    {
    fflush(stdin);
    printf("Qual o nome do aluno?");
    scanf("%['\n']",nome[*nalunos]); <- 2 erros
    scanf("%d",&numero[*nalunos]); <- 2 erros
    (*nalunos)++;
    }

    -> o que queres retirar dos scanf? é que n tens lá nenhum parametro (%i, %d, %f, etc...)
    -> nao precisas de usar o asterisco para acederes...

    vou começar a ver isto do inicio que tens uns quantos erros...ja posto o resto

    EDIT: pq raio n se havia de por printfs e scanfs fora do main?? :wow:
     
  4. S|N

    S|N Power Member

    Obrigado pelos replies :D o objectivo de %[\n] era ler tudo menos o \n. Como faço isso de outra maneira? Foi uma dica q me deram mas não sei ao certo como funciona.
     
  5. hasta.g5

    hasta.g5 I quit My Job for Folding

    Código:
    int indice;
    for (indice=0; indice<MAX_ALUNOS; indice++)
    {
    printf("%d%s\n",indice+1,nome[indice]);
    }
    Só por acaso isto não te dá erro quando não tens a lista cheia? Assim ele faz sempre MAX_ALUNOS procuras e se o array não tem esse tamanho.. *puf*!
     
  6. HiGhVoIcE

    HiGhVoIcE Power Member

    Código:
    #include <stdio.h>
    #include <string.h>
    #define MAX_ALUNOS 30
    #define MAX_NOME 60
    
    int main(void) {
    
    	int nalunos = 0;
    	int numero[MAX_ALUNOS];
    	int opcao;
    	char nome[MAX_NOME][MAX_ALUNOS];
    	
    
    	carregar_ficheiro();
    
    	do{
    		menu();
    		scanf("%d",&opcao);
    		switch (opcao){
    
    			case 1: op_inscrever_aluno(*numero, **nome, nalunos); break;
    			case 2: op_remover_aluno(); break;
    			case 3: op_listar_alunos(*numero, **nome, nalunos); break;
    		}
    	}while(opcao!=0);
    	guardar_ficheiro();
    
    	return 0;
    }
    

    não necessitas de andar sempre a fugir do \n, basta uma comparação...
    depois, podes usar os returns das funçoes para tua vantagem (ao invés de andar a trabalhar com apontador)

    por exemplo:

    int inscrever_aluno(int *numero, char **nome, int nalunos) {
    ...
    return nroalunos;
    }

    int main(){
    ...
    nrolunos += inscrever_aluno(numero[]
    ...
    }

    PS - ja n me lembro mt bem de apontadores :sad:
     
    Última edição: 22 de Abril de 2005
  7. hasta.g5

    hasta.g5 I quit My Job for Folding

    Para nós (pelo menos eu) nenhuma! :D
    Mas a mim, os profs disseram para não fazer. É qua assim, as funções podem ser usadas em qualquer programa e pode não se querer os printf's e os scanf's... :)
     
  8. S|N

    S|N Power Member

    Já agora podes me dizer como funcionam os parametros de exclusao do printf e scanf? Aquilo foi uma dica. será EX/pergunta: em printf("%['\n']) onde está a indicação para "ler tudo"? e "excepto \n"? (obvio esta ultima, mas queria uma pequena lição sobre isto). O uso de ponteiros é intencional (para aprender).
    Mais uma vez Obrigado.

    PS: acho q n ha nada de errado com MAX_ALUNOS. O programa deve estar estruturalmente correcto, uma vez que antes de tentar introduzir-lhe ponteiros compilava e funcionava sem erros.
     
  9. HiGhVoIcE

    HiGhVoIcE Power Member

    mas tu vais fazer uma biblioteca ou um programa especifico? parvoice...
     
  10. Karmack

    Karmack Power Member

    É um bocado dificil as pessoas ajudarem-te no teu programa. Acho-o demasiado grande. O melhor que tens a fazer é usar um debugger. O gdb é bastante bom. Podes correr o teu programa passo a passo e ver se o programa está a ter o comportamento esperado.
    Os IDE's dão a possibilidade de fazer debugging no editor o que é mais agradável (visualmente).
     
  11. S|N

    S|N Power Member

    Tou a fazer debugging mesmo agora. Manualmente. vê o meu outro topic - Erro rápido. Consegues ajudar?
    :)
     
  12. xBoShY

    xBoShY Power Member

    Hummm... pelo enunciado... pergunto.te: para que é que precisas de memoria dinamica se sabes que o maximo de alunos é 30?!?

    Para quê complicar? :rolleyes:

    Uma dica:
    Código:
    #define MAX_ALUNOS 30
    #define MAX_NOME 60
    
    struct aluno
    {
         int n_aluno;
         char nome_aluno[MAX_NOME+1];
    };
    
    struct aluno alunos[MAX_ALUNOS];
    E pronto... apartir daqui podes esquecer ponteiros...
     
  13. Madril

    Madril 1st Folding then Sex

    xBoshy parece k gostaste mesmo do teste de AED ....... :rolleyes: Fudidão :S
     
  14. xBoShY

    xBoShY Power Member

    Teste de AED? Akilo é que era bom para o S|N... era só ponteiros :lol:

    Os testes-tipo... esses não tinham nada haver com o que saiu :S
     
  15. HiGhVoIcE

    HiGhVoIcE Power Member

    ele só deve poder usar ponteiros dado que é para avaliação...
     
  16. xBoShY

    xBoShY Power Member

    Correcto... poderá ser para a avaliação... mas mesmo sendo para uma avaliação, não implica que seja necessário ponteiros! Tanto que neste problema em concreto, os ponteiros só servirão para xatear...

    E penso que nenhum prof, nem ninguem iria pedir um exercicio que usasse ponteiros e que tivesse um numero maximo de elementos (neste caso, alunos)...

    Só uso ponteiros quando kero um numero indeterminado de elementos (umas vezes pode ser 1 elemento, outras podem ser 99999, outras até mesmo 0...) Neste caso pedem 30 alunos no max... ou seja, pedem para usar um array com 30 elementos ;)

    [[]]
     
  17. S|N

    S|N Power Member

    É um exercício. O objectivo é eu aprender a usar ponteiros....

    Já agora. Alguem pode-me dizer como uso ponteiros numa funcao?

    tentei isto:

    tipo funcao (int *p)

    ao chamar o p vem &p

    mas no meu programa deu erro. Por isso tirei-lhe o *. Agora já n dá erro mas estarei a usar ponteiros assim?

    Alguem pode-me explicar na prática como faço e chamo uma funcao usando apontadores?
    Não vale a pena dizerem-me como usar apontadores de variáveis pq isso eu sei (felizmente). Só quando entram as funções é que eu já n sigo.

    Obrigado
     

Partilhar esta Página