Dificuldade em exercício com a utilização de Struct

1. Dificuldade em exercício com a utilização de Struct

felippe melo
melin

(usa Outra)

Enviado em 27/10/2021 - 23:09h

Olá, estou com dificuldade neste exercício de uma lista. Quando rodo o programa, o laço do for não funciona, ele para após o primeiro ciclo. Tem mudar alguma coisas para entender o que estava acontecendo, mas não consegui resolver. Acho que deve ter alguma coisa boba que eu não estou conseguindo ver e por isso a visão de outra pessoa iria e ajudar!

o enunciado: Escreva um programa que preencha, a partir do teclado, duas estruturas distintas do tipo vetor com as idades de 10pessoas.
A primeira estrutura do tipo vetor deverá receber somente as idades das pessoas do sexo masculino,
enquanto a segunda deverá armazenar as idades das pessoas do sexo feminino.
Após, o programa deverá exteriorizar os nomes, o sexo e as idades das pessoas que possuem idade
compreendida entre 20 (vinte) e 40 (quarenta) anos, inclusive.


#include <stdio.h>

struct masculino {
char nome[20];
int idade;
};

struct feminino {
char nome[20];
int idade;
};

int main(void){
char escolha;
int i;

struct masculino listam[10];
struct feminino listaf[10];

for (i = 0; i < 10; ++i){
printf("Digite M para adicionar uma mulher ou H para um homem\n"); //Essa mensagem deve aparecer 10 vezes para que cada vez o possa colocar uma pessoa com o sexo diferente
scanf("%c", &escolha);
if (escolha == 'h'){
printf("Digite o nome do homem\n");
scanf("%s", listam[i].nome);
printf("Digite a idade\n");
scanf("%i", listam[i].idade);
}
else{
printf("Digite o nome da mulher\n");
scanf("%s", listaf[i].nome);
printf("Digite a idade\n");
scanf("%i", listaf[i].idade);
}
}
for (i = 0; i < 10; ++i){
if ((listam[i].idade > 20 && listam[i].idade < 40) || (listaf[i].idade > 20 && listaf[i].idade < 40)){ //*a comparação para saber as idades de homens ou mulheres entre 20 e 40
printf("As pessoas com idade entre 20 e 40 anos sao\n");
printf("%s, %i, %s, %i \n", listam[i].nome, listam[i].idade, listaf[i].nome, listaf[i].idade);
}
else{
printf("Nenhuma pessoa tem idade entre 20 e 40 anos\n");
}
}

system("pause");
return 0;
}




  


2. Re: Dificuldade em exercício com a utilização de Struct

Paulo
paulo1205

(usa Ubuntu)

Enviado em 28/10/2021 - 08:35h

Bom dia, Melin.

melin escreveu:

Olá, estou com dificuldade neste exercício de uma lista. Quando rodo o programa, o laço do for não funciona, ele para após o primeiro ciclo. Tem mudar alguma coisas para entender o que estava acontecendo, mas não consegui resolver. Acho que deve ter alguma coisa boba que eu não estou conseguindo ver e por isso a visão de outra pessoa iria e ajudar!


Dizer que “não funciona” em geral não ajuda muito. É melhor ser mais específico sobre o que acontece.

Digo isso porque quando li o que você disse, que o for não está funcionando e que para após a primeira iteração, entendi que era um problema com a repetição em si, e que o programa seguia a diante com o fluxo depois no laço de repetição. Mas o problema real não está nos laços de repetição; mesmo sem ter compilado ou rodado o programa aqui do meu lado, eu imagino é que o problema é que o programa capota, quer travando, quer dando um erro como falha de segmentação ou outro tipo de exceção de acesso inválido à memória.

Por isso, insisto de novo, procure usar descrições mais precisas sobre o comportamento do programa. No seu caso, é um programa bem pequeno, mas considere como uma descrição imprecisa ou errônea pode atrasar o diagnóstico de possíveis bugs.

o enunciado: Escreva um programa que preencha, a partir do teclado, duas estruturas distintas do tipo vetor com as idades de 10pessoas.
A primeira estrutura do tipo vetor deverá receber somente as idades das pessoas do sexo masculino,
enquanto a segunda deverá armazenar as idades das pessoas do sexo feminino.
Após, o programa deverá exteriorizar os nomes, o sexo e as idades das pessoas que possuem idade
compreendida entre 20 (vinte) e 40 (quarenta) anos, inclusive.


Enunciado bem mal enunciado, por sinal (com o perdão do trocadilho). Nunca vi ninguém falar em “estruturas do tipo vetor”; suspeito que ele quis dizer “vetores de estruturas”.

#include <stdio.h>

struct masculino {
char nome[20];
int idade;
};

struct feminino {
char nome[20];
int idade;
};


Se você reparar bem, as duas estruturas têm exatemente o mesmo formato interno. E se você considerar que os atributos não têm nada a ver com o sexo, mas sim com a condição comum a todas as pessoas. Mais ainda: o enunciado, embora estranho, não pede tipos distintos de estruturas, mas sim vetores distintos para homens e mulheres. Tudo isso indica que você não precisa de dois tipos distintos, mas sim variáveis distintas para homens e mulheres, ambas do mesmo tipo “vetor de estruturas que representam pessoas”.

int main(void){
char escolha;
int i;

struct masculino listam[10];
struct feminino listaf[10];


Assumindo-se a simplificação de tipos proposta acima, você poderia declarar somente algo parecido com o seguinte.
struct pessoa homens[10], mulheres[10]; 

Eu mudei nomes dos vetores (por exemplo, de listam para homens) não apenas porque o tipo de dados não indica algo chamado de “lista” como uma estrutura de dados na qual cada elemento tem ponteiro(s) para o(s) elemento(s) vizinho(s), mas porque considero um desperdício gastar cinco caracteres em cada variável apenas para ficar repetindo a cada ocorrência qual o tipo de dado que ela supostamente tem. Entendo que o simples fato de ser um nome no plural já indica que tem mais de um elemento, e eu prefiro gastar caracteres de forma mais descritiva do conteúdo do que de sua suposta representação.


for (i = 0; i < 10; ++i){
printf("Digite M para adicionar uma mulher ou H para um homem\n"); //Essa mensagem deve aparecer 10 vezes para que cada vez o possa colocar uma pessoa com o sexo diferente
scanf("%c", &escolha);
if (escolha == 'h'){


Note que você pede para digitar “H” ou “M” (ambos maiúsculos), mas a única comparação que faz do valor digitado é com “h”. Se a pessoa digitar exatamente “H” (maiúsculo), que é exatamente uma das opções que você mostrou, o programa vai tentar ler os dados de uma mulher. E se você digitar "j", ou “123BaNanA”, também.

Sugiro obrigar o usuário a responder com consciência. Pode ser flexível, por exemplo, quanto a ser maiúsculo ou minúsculo, mas não para aceitar que se digite qualquer abobrinha, e proceder de um jeito que não é consistente com o que foi pedido.

Eis um jeito de o fazer.
char sexo;
// Usa laço de repetição para forçar usuário a digitar um dado válido.
do {
printf("Que tipo de pessoa deseja adicionar ('H' para homem, 'M' para mulher)? ");
if(scanf(" %c", &sexo)==1){ // Vê se leitura funcionou corretamente. Um espaço antes de %c: uma forma simples de descartar espaços em branco e quebras de linhas remanescentes de operações de leitura anteriores.
sexo=tolower(sexo); // Uniformiza, convertendo para minúscula. tolower() em <ctype.h>.
if(sexo=='h' || sexo=='m')
break; // Interrompe laço de repetição, pois o valor digitado foi válido.
}
else{
fprintf(stderr, "Erro de leitura: %s.\n", strerror(errno)); // strerror() em <string.h>; errno em <errno.h>.
exit(1); // Sai do programa em caso de erro, indicando falha (valor diferente de 0). exit() em <stdlib.h>.
}
fprintf(stderr, "O valor digitado não corresponde a um tipo de pessoa válido. Tente novamente.\n"); // Porque esse negócio de não-binário é invencionice moderna.
} while(true); // true em <stdbool.h>.

Lendo desse modo, aí sim você poderá ter certeza de que se não for homem, então é mulher.

			printf("Digite o nome do homem\n");
scanf("%s", listam[i].nome);


É uma boa prática verificar que todas as operações de leitura foram bem sucedidas antes de deixar o programa progredir, de modo parecido com o que eu mostrei acima.

			printf("Digite a idade\n");
scanf("%i", listam[i].idade);


Eis aí o erro do programa, que provavelmente o está fazendo capotar: o segundo argumento de scanf() e todos os argumentos subsequentes (se você lesse mais de um dado ao mesmo tempo) deveriam ser ponteiros, mas você passou um valor inteiro.

Provavelmente você quis dizer o seguinte (note o &).
scanf("%i", &listam[i].idade); 


				}
else{
printf("Digite o nome da mulher\n");
scanf("%s", listaf[i].nome);
printf("Digite a idade\n");
scanf("%i", listaf[i].idade);


Mesma coisa aqui.

			}
}


Uma observação sobre o laço de repetição, com um exemplo que acho que ilustrará bem o problema.

Suponha que você leu dados de dez pessoas, mas sempre alterando um homem, uma mulher, um homem, uma mulher etc. Concorda que você vai ter dados de homens preenchidos apenas nos índices 0, 2, 4, 6, e 8 do vetor, e mulheres apenas nos índices 1, 3, 5, 7 e 9, e que todos elementos dos respectivos vetores que não tiverem sido preenchidos vão ficar com dados indeterminados?

Esse problema vai impactar a saída do próximo laço de repetição, que vai ter grandes chances de imprimir lixo para pelo menos uma parte dos resultados.

Você consegue imaginar como pode fazer para corrigir isso?

for (i = 0; i < 10; ++i){
if ((listam[i].idade > 20 && listam[i].idade < 40) || (listaf[i].idade > 20 && listaf[i].idade < 40)){ //*a comparação para saber as idades de homens ou mulheres entre 20 e 40
printf("As pessoas com idade entre 20 e 40 anos sao\n");
printf("%s, %i, %s, %i \n", listam[i].nome, listam[i].idade, listaf[i].nome, listaf[i].idade);
}
else{
printf("Nenhuma pessoa tem idade entre 20 e 40 anos\n");


Tem certeza de que você quer ter esse bloco else com essa mensagem dentro do bloco de repetição?

				}
}

system("pause");


system("pause") é uma excrescência. Não se vicie em usar esse tipo de coisa, ainda mais para uma função tão simples quanto fazer uma pausa com uma mensagem. Chamar programas externos, que é o que system() faz, é ineficiente, pode não funcionar em máquinas diferentes da sua, é sujeito a problemas de segurança, e deve, por isso, ser evitado ao máximo, cabendo ser usado apenas quando for imprescindível.

Uma alternativa a system("pause"), usando apenas funções padronizadas do C que funcionam em qualquer máquina, pode ser a seguinte.
printf("Tecle <Enter> para prosseguir...");
for(int ch; (ch=getchar())!=EOF && ch!='\n';) ;


	return 0;
}





... Então Jesus afirmou de novo: “(...) eu vim para que tenham vida, e a tenham plenamente.” (João 10:7-10)






Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts