paulo1205
(usa Ubuntu)
Enviado em 17/06/2018 - 17:07h
Antes de falar do código em si, é preciso ter uma noção exata de o quê você quer fazer.
Pelas declarações dentro de
main(), você tem uma tabela de 5 nomes, que podem ter até 50 caracteres cada um (49 válidos, mais um para o
byte terminador da
string), uma tabela para 5 notas, com o pouco esclarecedor nome “
n” e aparentemente desvinculada da tabela de nomes, e uma outra tabela (
nt, que também é um nome pouco esclarecedor sobre sua função no código), que parece ainda mais desvinculada das demais, por ter uma quantidade diferente de elementos (10, em vez de 5), onde você acaba guardando a média associada a cada nome.
Seria importante saber o que você quer efetivamente guardar. É apenas o nome e a média (usando a leitura das notas apenas como uma passo intermediário para chegar ao valor da média que se quer guardar), ou seria cada nome e cada uma das notas daquele aluno (caso em que seria redundante guardar também o valor da média, pois ela poderia ser (re)calculada apenas na hora de imprimir os dados do aluno)?
É importante saber essas coisas porque, de acordo com as respostas, as declarações podem estar ou insuficientes ou excessivas (além de estarem em descompasso entre si, como já se viu acima).
Fora isso, permita-me trazer a você o mesmo aviso e a mesma sugestão que trago a todos os novatos em C que se deparam com
scanf() pelas primeiras vezes.
scanf() é uma das funções mais complexas (se não for *A* mais complexa) de toda a biblioteca de funções padronizadas do C, e requer conhecimento pelo menos razoável de ponteiros (que geralmente só são apresentados de forma mais sistemática aos alunos bem depois que eles já se frustraram um bocado com as aparentes idiossincrasias de
scanf()). Por isso, leia com muito cuidado sua documentação (dica: a documentação de
scanf() que vem com o Linux, na forma de
man page, é excelente, podendo ser ser vista
on-line em
http://man7.org/linux/man-pages/man3/scanf.3.html e outros sites; a da Microsoft, até a última vez que eu vi (VS2015), não era nada boa, mas como
scanf() é uma função padronizada, você pode se reportar à do Linux, mesmo que use Windows).
dalison escreveu:
#include <stdio.h>
#include <stdlib.h>
int main() {
int i, j, l, n1, contador;
float soma, media;
char nome[5][50];
char n[5], nt[10];
char tecla;
for(;;){
/*Ler uma lista de nomes.*/
for(i=0; i<5; i++){
for(j=0; j<49; j++){
printf("Digite o nome do jogador");
scanf("%[a-z A-Z]", &nome[i][j]);
getchar();
}
O bloco marcado acima está errado. O que ele faz é mandar ler um nome 49 vezes, sempre começando uma posição à frente no
i-ésimo elemento do vetor de nomes.
Você provavelmente quis dizer mais ou menos o seguinte (suprimindo o laço de repetição indexado por
j):
printf("Digite o nome do %dº jogador: ", i+1);
int a=0, b=0;
if(scanf(" %49[^\n]%n%*1[\n]", nome[i], &a, &b)!=1 || a=0 || b-a<1){
fprintf(stderr, "Leitura inválida. Abortando programa.\n");
exit(1);
}
/*Ler as notas.*/
for(l=0; l<5; l++){
printf("Digite a nota\n");
scanf("%d", &n[l]);
getchar();
Esse
getchar(), que suponho ser para se livrar da marca de fim de linha após a leitura do número, pode ser tanto desnecessário (se você usar um espaço antes da conversão de
string, como eu mostrei acima no código que sugeri acima) quanto insuficiente (se houver outros caracteres após o número e antes da marca de fim de linha) para preparar o programa para a próxima leitura de um nome.
A rigor, porém, você deveria verificar o valor de retorno de
scanf(), pois pode acontecer de o usuário digitar um valo não numérico desde o início, e isso pode deixar seu programa ainda mais disparatado.
while(scanf("%d", &n[l])!=1){
if(ferror(stdin) || feof(stdin)){
fprintf(stderr, "Erro de leitura. Abortando programa.\n");
exit(1);
}
/* Algum caráter não-numérico foi digitado. Remove-o(s) do buffer de leitura e tenta novamente. */
int ch;
while((ch=getchar())!=EOF && ch!='\n')
;
if(ch==EOF){
fprintf(stderr, "Erro de leitura. Abortando programa.\n");
exit(1);
}
printf("Dados inválidos. Digite novamente a %dª do %dº aluno: ", l+1, i+1);
}
soma = soma + n[l];
contador++;
Perceba que você não zerou o valor de
soma antes de começar a acumular valores nela, nem tampouco o valor de
contador. O cálculo da média claramente vai ficar prejudicado.
media = soma/contador;
nt[i] = media;
i++;
}
/*Mostra um lista.*/
for(i=0; i<10; i++){
for(j=0; j<49; j++){
printf("jogador %s, media: %f\n", nome[i][j], nt[i]);
Note que aqui você varia
i de 0 a 9, mas os índices válidos para
nome são apenas de 0 a 4.
Mas pior do que isso é o fato de que você fez um segundo
for usando
i como variável de controle dentro de um outro
for que já a usava como variável de controle. É óbvio que um vai interferir com o outro.
Ou você antecipa o encerramento do
for mais externo (parece ser o mais lógico), ou você muda a variável de controle de um deles.
Lembre-se de que não vai bastar apertar
s, mas também teclar
Enter. Seria bom, também, informar ao usuário que ele deve digitar alguma coisa, e o porquê disso.
if(tecla == 's'){
exit(0);
}
}
}
return 0;
}