PsySc0rpi0n Posted June 22, 2013 at 02:03 PM Report #514453 Posted June 22, 2013 at 02:03 PM Tenho aqui alguns exames e estou a tentar resolvê-los... Citação 2. Escreva um programa que permite gerir o IMC (índice da massa corporal). Crie uma estrutura de dados que permita guardar o nome de uma pessoa, o peso (Kg) e a altura (m). a) Escreva uma função que peça os dados de uma pessoa e os devolva. Os dados inseridos relativamente ao peso e à altura só devem ser aceites se forem superiores a 30Kg e 1m, respectivamente. b) Escreva uma função que recebe o endereço de uma estrutura e o nome do ficheiro e acrescenta a estrutura lida ao ficheiro. c) Escreva uma função que consulta os dados armazenados no ficheiro e, para cada registo guardado no ficheiro, calcula o IMC IMC = peso altura 2 e escreve no monitor uma das frases: IMC entre 18.6 e 24.9: Nome da pessoa, IMC, “Peso normal.” IMC menor 15 ou maior 40: Nome da pessoa, IMC, “Por favor consulte o seu médico!” d) Escreva um programa que implemente o seguinte menu: MENU: 1 – Inserir novo registo e guardar em ficheiro 2 - Calcular IMC 3 - Sair E fiz o seguinte code mas tem alguns problemazitos que queria que me ajudassem a resolvê-los #include <stdio.h> #include <ctype.h> #include <string.h> #include <stdlib.h> #include <math.h> typedef struct{ char nome[50]; float peso; float altura; } Dados; #define CLEAR_INPUT while (getchar ()!= '\n') #define CLEAR_SCREEN puts("\x1b[H\x1b[2J") //Alínea a) que pede os dados de uma pessoa e os guarda na estrutura Dados pessoa. //Verifica também se o peso e a altura são superiores a 30 e a 1 respectivamente. //Se não forem, volta a pedir os dados até que sejamsuperiores a 30 e a 1... Dados PedeDados(){ Dados pessoa; printf("Introduza o nome:\n"); CLEAR_INPUT; fgets(pessoa.nome, 50, stdin); if((pessoa.nome[strlen(pessoa.nome) - 1]) == '\n') pessoa.nome[strlen(pessoa.nome) - 1] = '\0'; do{ printf("Introduza o peso:\n"); scanf("%f", &pessoa.peso); if(pessoa.peso <= 30) printf("O peso tem que ser superior a 30Kg!\n"); }while(pessoa.peso <= 30); do{ printf("Introduza a altura:\n"); scanf("%f", &pessoa.altura); if(pessoa.altura <= 1) printf("A altura tem que ser superior a 1 metro!\n"); }while(pessoa.altura <= 1); return pessoa; } //Alínea b) pede uma função que recebe um ponteiro para uma estrutura e o nome //de um ficheiro para guardar a estrutura nesse ficheiro int EscreveEstruturaFicheiro(Dados *pessoa, char *nomeficheiro){ FILE *pficheiro; if((pficheiro = fopen(nomeficheiro, "r+b")) == NULL){ printf("Erro ao aceder ao ficheiro!\n"); return -1; } fseek(pficheiro, 0, SEEK_END); fwrite(pessoa, sizeof(Dados), 1, pficheiro); fclose(pficheiro); return 0; } //Alínea c) que lê os dados do ficheiro e calcula o IMC para cada dado lido int ConsultaDadosEscreveMonitor(){ FILE *pficheiro; float imc; Dados *pessoatmp = NULL; if((pficheiro = fopen("dadospessoa.bin", "r+b")) == NULL){ printf("Erro ao aceder ao ficheiro!\n"); return -1; } while(fread(pessoatmp, sizeof(Dados), 1, pficheiro) != 0){ imc = (pessoatmp->peso)/(pow(pessoatmp->altura, 2)); if((imc >= 18.6) && (imc <= 24.9)) printf("%s, %.2f, Peso Normal!\n", pessoatmp->nome, imc); if((imc < 15) || (imc > 40)) printf("%s, %.2f, \"Por favor consulte o seu médico!\"\n", pessoatmp->nome, imc); } fclose(pficheiro); return 0; } //Alínea d) que pede o menu para usar as funções criadas anteriormente int main (void) { char op; Dados pessoa; char nomeficheiro[25] = "dadospessoa.bin"; CLEAR_SCREEN; do{ printf("\t\tMENU\n"); printf("\t(I)nserir novo registo e guardar em ficheiro\n"); printf("\t(C)alcular IMC\n"); printf("\t(S)air\n"); scanf(" %c", &op); switch(tolower(op)){ case 'i': pessoa = PedeDados(); EscreveEstruturaFicheiro(&pessoa, nomeficheiro); break; case 'c': ConsultaDadosEscreveMonitor(); break; case 's': break; default : printf("Opção inválida!\n"); } }while(op != 's'); getchar (); return 0; } O primeiro problema é que quando peço os dados da pessoa, ele está a passar o nome em falso... Porquê? Kurt Cobain - Grunge misses you Nissan GT-R - beast killer
thoga31 Posted June 22, 2013 at 02:26 PM Report #514455 Posted June 22, 2013 at 02:26 PM Eu (ainda) não sou grande um conhecedor de C, pelo que te vou apontar apenas duas incongruências no teu código: do{ // whatever if(pessoa.peso < 30) printf("O peso tem que ser superior a 30Kg!\n"); }while(pessoa.peso <= 30); do{ // whatever if(pessoa.altura <= 1) printf("A altura tem que ser superior a 1 metro!\n"); }while(pessoa.altura <= 1); Na condição de saída do while tens <= e no if tens <. Decide qual deles queres. Se alguém introduzir um peso de 30 Kg, o programa não avisa mas o ciclo também não é interrompido. Knowledge is free!
PsySc0rpi0n Posted June 22, 2013 at 02:30 PM Author Report #514457 Posted June 22, 2013 at 02:30 PM Eu (ainda) não sou grande um conhecedor de C, pelo que te vou apontar apenas duas incongruências no teu código: do{ // whatever if(pessoa.peso < 30) printf("O peso tem que ser superior a 30Kg!\n"); }while(pessoa.peso <= 30); do{ // whatever if(pessoa.altura <= 1) printf("A altura tem que ser superior a 1 metro!\n"); }while(pessoa.altura <= 1); Na condição de saída do while tens <= e no if tens <. Decide qual deles queres. Se alguém introduzir um peso de 30 Kg, o programa não avisa mas o ciclo também não é interrompido. Obrigado... Bem visto... Erro meu... Se conseguires ajudar-me na minha questão inicial, agradecia! Kurt Cobain - Grunge misses you Nissan GT-R - beast killer
thoga31 Posted June 22, 2013 at 02:31 PM Report #514458 Posted June 22, 2013 at 02:31 PM Como disse, ainda não sou grande conhecedor de C, há aqui quem perceba potes acima de mim 😛 Anyway, o que queres dizer com "ele está a passar o nome em falso"? Knowledge is free!
PsySc0rpi0n Posted June 22, 2013 at 02:47 PM Author Report #514462 Posted June 22, 2013 at 02:47 PM Não me deixa inserir o nome. É algum caractere que está a passar para o fgets e depois o programa passa logo para o peso. Mas esse até já resolvi... Agora está outro problema na função que consulta os dados do ficheiro e os escreve no ecrã. Está-me a dar falha de segmentação. Kurt Cobain - Grunge misses you Nissan GT-R - beast killer
HappyHippyHippo Posted June 22, 2013 at 02:48 PM Report #514463 Posted June 22, 2013 at 02:48 PM (edited) O primeiro problema é que quando peço os dados da pessoa, ele está a passar o nome em falso... Porquê? enquanto não elucidares a comunidade o que queres dizer com isto, acho pouco provável que terás muito sucesso na resolução do problema. no entanto, vejo um problema muito pior ao referido pelo @thoga31 (se fosse pascal ele diria logo qual seria o problema 😄 , por outro lado, eu não 😄 ) int ConsultaDadosEscreveMonitor(){ FILE *pficheiro; float imc; Dados *pessoatmp = NULL; // <--- isto é um ponteiro, não existe um espaço de memória para guardar os dados da estrutura Dados Dados pessoa; // <--- uma instância da estrutura Dados if((pficheiro = fopen("dadospessoa.bin", "r+b")) == NULL){ printf("Erro ao aceder ao ficheiro!\n"); return -1; } while(fread(pessoatmp, sizeof(Dados), 1, pficheiro) == 1){ // <---- estás a usar um ponteiro para nada que na realidade aponta para NULL // que deverá lançar um segmentation fault !! while(fread(&pessoa, sizeof(Dados), 1, pficheiro) == 1){ // leitura correcta imc = (pessoatmp->peso)/(pow(pessoatmp->altura, 2)); if((imc >= 18.6) && (imc <= 24.9)) printf("%s, %.2f, Peso Nomral!\n", pessoatmp->nome, imc); if((imc < 15) || (imc > 40)) printf("%s, %.2f, \"Por favor consulte o seu médico!\"\n", pessoatmp->nome, imc); } fclose(pficheiro); return 0; } Edited June 22, 2013 at 03:12 PM by HappyHippyHippo IRC : sim, é algo que ainda existe >> #p@p Portugol Plus
PsySc0rpi0n Posted June 22, 2013 at 03:10 PM Author Report #514469 Posted June 22, 2013 at 03:10 PM (edited) Ok, já corrigi e coloquei assim: //Alínea c) que lê os dados do ficheiro e calcula o IMC para cada dado lido int ConsultaDadosEscreveMonitor(){ FILE *pficheiro; float imc; Dados pessoatmp; if((pficheiro = fopen("dadospessoa.bin", "rb")) == NULL){ printf("Erro ao aceder ao ficheiro para consulta!\n"); return -1; } while(fread(&pessoatmp, sizeof(Dados), 1, pficheiro) != 0){ imc = (pessoatmp.peso)/(pow(pessoatmp.altura, 2)); if((imc >= 18.6) && (imc <= 24.9)) printf("%s, %.2f, Peso Nomral!\n", pessoatmp.nome, imc); if((imc < 15) || (imc > 40)) printf("%s, %.2f, \"Por favor consulte o seu médico!\"\n", pessoatmp.nome, imc); } fclose(pficheiro); return 0; } Não percebi porque dizes que a leitura dos dados está a ser mal feita e por isso alterei a comparação do while de == 1 para !=0... Não sei se era a isto a que te referias, happyhippy... Mas não me mostra nada do que tenho no ficheiro... Ainda não fiz contas mas só se as contas não estiverem incluídas em nenhuma das condições dos dois if's... Bem, pelos vistos, o code estava bem mesmo com o == 1 no fread... Acontece que o enunciado não contempla valores maiores que 24.9 e menores que 40... Não sei qual é a lógica mas ok... Como os meus valores de IMC davam 27.7, os dois if's falhavam as condições e por isso não mostravam nada... Vou passar ao exercício das listas ligadas... Edited June 22, 2013 at 03:11 PM by PsySc0rpi0n Kurt Cobain - Grunge misses you Nissan GT-R - beast killer
HappyHippyHippo Posted June 22, 2013 at 03:13 PM Report #514472 Posted June 22, 2013 at 03:13 PM Não percebi porque dizes que a leitura dos dados está a ser mal feita e por isso alterei a comparação do while de == 1 para !=0... Não sei se era a isto a que te referias, happyhippy... eu disse que estava a ser mal feita pela razão que alteras-te e corrigiste o código ... IRC : sim, é algo que ainda existe >> #p@p Portugol Plus
PsySc0rpi0n Posted June 22, 2013 at 03:17 PM Author Report #514473 Posted June 22, 2013 at 03:17 PM eu disse que estava a ser mal feita pela razão que alteras-te e corrigiste o código ... Mas com o == 1 não funcionava? Devia funcionar já que o fread retorna o número de elementos lidos com sucesso... Por isso, pelo menos, pensei que devia funcionar! Kurt Cobain - Grunge misses you Nissan GT-R - beast killer
thoga31 Posted June 22, 2013 at 03:19 PM Report #514474 Posted June 22, 2013 at 03:19 PM O problema não estava no ==1, não reparaste que alteraste todo o fread?... Knowledge is free!
HappyHippyHippo Posted June 22, 2013 at 03:19 PM Report #514475 Posted June 22, 2013 at 03:19 PM e funciona IRC : sim, é algo que ainda existe >> #p@p Portugol Plus
PsySc0rpi0n Posted June 22, 2013 at 03:24 PM Author Report #514476 Posted June 22, 2013 at 03:24 PM Ok... Então o fread não estava mal... O que estava mal era a variável estar a apontar para null... E como consequência, o fread já dava problemas... Agora o exercício das listas ligadas diz: 3. Considere que os dados dos jogadores de todas equipas de Futebol da 1a divisão Portuguesa se encontram guardadas numa lista ligada cujos nós são do seguinte tipo struct jogadoresPrimeiraDivisao{ char Pais [50]; char Nome [50]; unsigned short int idade; struct jogadoresMundial *prox; }; Escreva uma função que recebe como parâmetro o endereço do primeiro elemento da lista e retorne a idade do jogador mais novo, a idade média dos jogadores e o número de jogadores de nacionalidade Portuguesa. Seria ilegítimo criar, não uma, mas sim 4 funções? Uma para o jogador mais novo da lista, outra para a idade média dos jogadores e outra para o número de jogadores de nacionalidade portuguesa. No final, haveria uma outra que iria chamar cada uma das 3 anteriores... Kurt Cobain - Grunge misses you Nissan GT-R - beast killer
HappyHippyHippo Posted June 22, 2013 at 03:31 PM Report #514478 Posted June 22, 2013 at 03:31 PM depende do professor. visto que estás a praticar, faz as duas soluções IRC : sim, é algo que ainda existe >> #p@p Portugol Plus
Rui Carlos Posted June 23, 2013 at 09:12 AM Report #514544 Posted June 23, 2013 at 09:12 AM O exercício não obriga a usar apenas uma função, pelo que acho que faz todo o sentido ter as 3 funções em separado. (Por outro lado, ao usares 3 funções, vais percorrer a lista 3 vezes, o que ainda assim não me parece muito problemático.) Rui Carlos Gonçalves
PsySc0rpi0n Posted June 23, 2013 at 08:57 PM Author Report #514617 Posted June 23, 2013 at 08:57 PM (edited) Este já foi feito... Se quiserem coloco aqui o code par comentarem... E já resolvi mais uns quantos... Mas como digo, os enunciados criam sempre ambiguidade... Deixam sempre dúvidas... Quando se fala numa função que retorna um valor, não pressupõe o uso da palavra reservada "return"? Eu entendo que sim. Ora, se um enunciado pede para uma função RETORNAR 3 valores, das duas uma: Ou não se respeita o enunciado e não se usa a palavra reservada "return" recorrendo-se a ponteiros ou então o exercício é impossível de se fazer seguindo à risca o enunciado. Isto é a minha opinião! Estou a fazer este agora: Construa uma função que permite comparar o tamanho de caracteres de dois ficheiros de texto. A funçãorecebe o nome dos dois ficheiros a comparar e devolve: 0 (zero) se os ficheiros tiverem exatamente o mesmo número de caracteres; -1 (menos um) se o primeiro ficheiro for maior que o segundo; 1 (um) se o segundo ficheiro for maior que o primeiro. Para já, acho que "comparar o tamanho de caracteres de dois ficheiros" não faz sentido. O tamanho de caracteres é sempre 1 byte, certo? Devia estar escrito "comparar o número de caracteres de dois ficheiros". Depois, espaços e mudanças de linha, devem contar como caracteres ou não? Bem, eu nem sei como vou fazer isto mas vou pensar um pouco... Edited June 23, 2013 at 09:11 PM by PsySc0rpi0n Kurt Cobain - Grunge misses you Nissan GT-R - beast killer
Rui Carlos Posted June 23, 2013 at 11:12 PM Report #514634 Posted June 23, 2013 at 11:12 PM Este já foi feito... Se quiserem coloco aqui o code par comentarem... E já resolvi mais uns quantos... Mas como digo, os enunciados criam sempre ambiguidade... Deixam sempre dúvidas... Quando se fala numa função que retorna um valor, não pressupõe o uso da palavra reservada "return"? Eu entendo que sim. Ora, se um enunciado pede para uma função RETORNAR 3 valores, das duas uma: Ou não se respeita o enunciado e não se usa a palavra reservada "return" recorrendo-se a ponteiros ou então o exercício é impossível de se fazer seguindo à risca o enunciado. Isto é a minha opinião! Nada te impede de retornar um apontador para um array para 3 valores, ou para uma struct com 3 valores, por exemplo. Para já, acho que "comparar o tamanho de caracteres de dois ficheiros" não faz sentido. O tamanho de caracteres é sempre 1 byte, certo? Devia estar escrito "comparar o número de caracteres de dois ficheiros". Depois, espaços e mudanças de linha, devem contar como caracteres ou não? Bem, eu nem sei como vou fazer isto mas vou pensar um pouco... O meu conselho é contares o número de bytes (é que se queres complicar, então também ias ter que saber o encoding do ficheiro). Rui Carlos Gonçalves
PsySc0rpi0n Posted June 24, 2013 at 05:45 PM Author Report #514794 Posted June 24, 2013 at 05:45 PM Pois, já são pormenores que requerem alguma experiência... Bem o exame está feito... O exame era isto: http://img809.imageshack.us/img809/3391/w25t.jpg Vou deixar o code que escrevi para cada pergunta: 1) int contaNPrimos (int *vector, int N){ int i, ok = 0, contaprimos = 0; for(i = 0; i < N; i++){ ok = primo(*(vector + i)); if(ok == 1) contaprimos++; } return contaprimos; } 2.a) typedef strcut{ int cod; char cat; char *nome[50];//O * está errado. Já não sei se o corrigi a passar para a folha de ponto ou não... }UTENTE; 2.b) void MostraDados(UTENTE paciente){ printf("O código do utente é %d\n", paciente.cod); printf("A categoria do utente é %d\n", paciente.cat);//aqui devo-me ter enganado e coloquei %d em vez de %c mas já não me recordo printf("O nome do utente é %s\n", paciente.nome); } 2.c) int ValorPagaCat(char cat){ switch(tolower(cat)){ case 'a': return 1; case 'b': return 2; case 'c': return 3; default: printf("Categoria inválida!\n"); } } 2.d) void imprimeTicket(char *nomeficheiro, int codutente){ FILE *fp; UTENTE paciente; int ok = 0; if((fp = fopen(nomeficheiro, "rb")) == NULL){ printf("Erro ao aceder ao ficheiro para leitura!\n"); return -1; } while((fread(&paciente, sizeof(UTENTE), 1, fp)) != 0){ if(codutente == paciente.cod){ MostraDados(paciente); printf("O valor a pagaré %d €!\n", ValorPagarCat(paciente.cat)); ok = 1; } } if(!ok) printf("Não foi encontrado nenhum utente com o código fornecido!\n"); } 3) int contaCaracteres(char *nomeficheiro){ int i, contaLetra = 0; char letra; FILE *fp; if((fp = fopen(nomeficheiro, "r")) == NULL){ printf("Erro ao aceder ao ficheiro para leitura!\n"); return -1; } while((fread(&letra, sizeof(char), 1, fp)) == NULL){ if((strcmp(letra, "#") == 0) || (strcmp(letra, "@")==0)) contaletra++; } return contaLetra; } 4) char *Partido(ELEICOES *partido){//aqui era para ter devolvido os resultados mas acabei por mostrar os resultados na própria função. Portanto ficou mal aqui int maior = partido->votos, menor = partido->votos; char partidomais[50] = partido->nome, partidomenos[50] = partido->nome;//tanto nesta inicialização como na anterior, não sei se deixei ficar, sem querer, um asterisco antes do nome das variáveis. Se deixei, não devia... while((partido->prox) != NULL){ if(partido->votos > maior) //aqui se calhar devia ter colocado os parêntesis à volta do partido->votos e não coloquei! maior = partido->votos; strcpy(partidomenos, partido->nome); } if(partido->votos < menor){ menor = partido->votos; strcpy(partidomenos, partido->nome); } partido = partido->prox; }//acho que me esqueci de fechar este parêntesis do while printf("O partido mais votado foi %s e o menos votado foi %s!\n", partidomais, partidomenos); } E foi isto. O exame era fácil e fora algumas distracções, espero que esteja tudo minimamente aceitável... Kurt Cobain - Grunge misses you Nissan GT-R - beast killer
HappyHippyHippo Posted June 24, 2013 at 06:28 PM Report #514803 Posted June 24, 2013 at 06:28 PM (edited) de quanto tempo era isso ? 1) int conta_primos (int *vector, int N) { int i, total = 0; for (i = 0; i < N; i++) total += primo(vector[i]); return total; } 2.a) enum Categoria { A = 'A', B = 'B', C = 'C' }; struct Utente { int codigo; enum Categoria categoria; char nome[64]; }; 2.b) void apresenta_utente (struct Utente utente) { printf("Utente\n"); printf("\tCodigo : %d\n", utente.codigo); printf("\tCategoria : %c\n", utente.categoria); printf("\tNome : %s\n", utente.nome); } 2.c) // double para poder usar centimos double valor_a_pagar (enum Categoria categoria) { return (double)categoria - 'A' + 1; } 2.d) int imprimeTicket (const char * filename, int codigo) { struct Utente utente; FILE * file = NULL; if (filename == NULL || (file = fopen(filename, "rb")) == NULL) { // deixar tratamento de erro para a função que chamou return -1; } while (fread(&utente, sizeof(struct Utente), 1, file)) { if (utente.codigo == codigo) { apresenta_utente(utente); printf("\nValor a pagar : %d\n", valor_a_pagar(utente.categoria)); fclose(file); return 0; } } fclose(file); // <------ nunca esquecer !!!!! return -2; } 3) int conta_caracteres (const char * filename) { int total = 0; FILE * file = NULL; int c; if (filename == NULL || (file = fopen(filename, "r")) == NULL) { // deixar tratamento de erro para a função que chamou return -1; } while ((c = fgetc(file)) != EOF) { total += c == '#' || c == '@'; } fclose(file); // <------ nunca esquecer !!!!! return total; } 4) int menor_e_maior(struct Eleicoes * lista, char * menor, char * maior) { struct Eleicoes * pt_menor = lista, * pt_maior = lista; if (lista == NULL || menor == NULL || maior == NULL) { return -1; } lista = lista->prox; while (lista != NULL) { if (lista->votos < pt_menor->votos) { pt_menor = lista; } if (lista->votos > pt_maior->votos) { pt_maior = lista; } lista = lista->prox; } strpcy(menor, pt_menor->partido); strpcy(maior, pt_maior->partido); return 0; } ------ edit : no exercício 3, a variável "c" foi alterada para int (EOF requirmenet) Edited June 24, 2013 at 07:26 PM by HappyHippyHippo IRC : sim, é algo que ainda existe >> #p@p Portugol Plus
PsySc0rpi0n Posted June 24, 2013 at 11:00 PM Author Report #514853 Posted June 24, 2013 at 11:00 PM Eram 2 horas... Não demos o tipo de dados "enum"... Kurt Cobain - Grunge misses you Nissan GT-R - beast killer
PsySc0rpi0n Posted June 25, 2013 at 06:16 AM Author Report #514868 Posted June 25, 2013 at 06:16 AM Eu tentei seguir o mais à risca possível os enunciado. No exercício 4, se calhar devia ter enviado os resultados como tu fizeste em vez de os ter apresentado na própria função... Mas do que fiz, está muito mal ou devo-me safar? O exame estava cotado para 14. Os outros 6 valores eram para o projecto. E esses 6, já estão garantidos... Kurt Cobain - Grunge misses you Nissan GT-R - beast killer
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now