Mudanças entre as edições de "AULA 13 - Programação 1 - Engenharia"
Linha 17: | Linha 17: | ||
+ | |||
+ | <blockquote style="background: #DCF4CC; border: 1px solid black; padding: 1em;"> | ||
<blockquote style="background: #DCF4CC; border: 1px solid black; padding: 1em;"> | <blockquote style="background: #DCF4CC; border: 1px solid black; padding: 1em;"> |
Edição das 14h47min de 28 de julho de 2020
Objetivos
Ao final desta Unidade o aluno deverá ser capaz de:
- Conceituar estruturas e campos de estruturas em C, através de exemplos de utilização;
- Criar tipos com 'struct' e definir/declarar estruturas;
- Inicializar estruturas na definição;
- Acessar campos de uma estrutura e usar estruturas em sentenças/expressões;
- Passar estruturas como parâmetros de funções (via cópia) e retornar estruturas em funções;
- Copiar uma variável estrutura para outra variável;
- Criar e usar estruturas como campo de outras estruturas;
- Criar arranjos de estruturas.
Definição/declaração de estruturas
No C é possível criar tipos de dados que representam uma estrutura. Veja o exemplo seguinte
#include <stdio.h> struct TUsuario /* struct TUsuario é o nome do tipo que está sendo criado */ { char userID[20]; char senha[20]; int num_acessos; } Usuario; /* aqui é definida uma variável do tipo struct TUsuario */ /* aqui uma tabela/vetor de estruturas */ struct TUsuario TabelaUsuario[20]; main() { /* acessando os campos da estrutura Usuario */ scanf("%s", Usuario.userId); scanf("%s", Usuario.senha); Usuario.num_acessos=0; /* acessando o campo 10 da tabela de estruturas */ scanf("%s", TabelaUsuario[10].userID); scanf("%s", TabelaUsuario[10].senha); }Neste exemplo, foi definido um tipo (modelo) para o registro (struct TUsuario) e foi criada uma variável chamada Usuario a partir deste tipo. Na sequência foi criada mais uma variável (um vetor de estruturas) chamada TabelaUsuario. Note que basta usar as palavras chave struct Usuario para criar novas variáveis. O tipo completo é definido uma única vez no início.
Exercícios
1. Criar um tipo estrutura que permita representar um retângulo. Criar duas variáveis retângulo e mostrar como as áreas destes retângulos poderiam ser somadas.
#include <stdio.h> struct tipo_retang{ float lado1; float lado2; }; main() { struct tipo_retang x,y; float area_final; x.lado1=5.5; x.lado2=6.7; y.lado1=2.3; y.lado2=7.9; /* poderia entrar com scanf: scanf("%f",&y.lado2); etc */ area_final = x.lado1*x.lado2 + y.lado1*y.lado2; printf("Área total dos dois retângulos = %f \n", area_final); }2. Criar um tipo estrutura que permita armazenar os coeficientes de uma equação do segundo grau. Implementar um código para calcular o DELTA da equação.
solução Ex. 2 //Autor : Victor Cesconetto De Pieri #include <stdio.h> struct Equacao { float delta,a,b,c; } eq; main() { printf("Entre com o 'a' da equação\n"); scanf("%f", &eq.a); printf("Entre com o 'b' da equação\n"); scanf("%f", &eq.b); printf("Entre com o 'c' da equação\n"); scanf("%f", &eq.c); eq.delta = (eq.b*eq.b) - 4*eq.a*eq.c; printf("delta : %f\n", eq.delta); }3. Criar um programa que define uma struct para armazenamento do nome e das notas bimestrais de um aluno. Atualizar a estrutura usando o scanf.
solução Ex. 3 #include <stdio.h> #define NUM_MAX 3 struct TAluno { char nome[30]; char matricula[11]; float b1,b2,b3,b4; } Turma[NUM_MAX]; int main() { int i; for(i=0;i<NUM_MAX;i++) { printf("Entre com o nome do aluno\n"); scanf("%s", Turma[i].nome); printf("Entre com a matrícula do aluno\n"); scanf("%s", Turma[i].matricula); printf("Entre com a nota do bimestre 1\n"); scanf("%f", &Turma[i].b1); printf("Entre com a nota do bimestre 2\n"); scanf("%f", &Turma[i].b2); printf("Entre com a nota do bimestre 3\n"); scanf("%f", &Turma[i].b3); printf("Entre com a nota do bimestre 4\n"); scanf("%f", &Turma[i].b4); } return 0; }4. Acrescentar um código no final da função main para calcular a média da turma para cada um dos bimestres.
solução Ex. 4 #include <stdio.h> #define NUM_MAX 3 struct TAluno { char nome[30]; char matricula[11]; float b1,b2,b3,b4; } Turma[NUM_MAX]; int main(){ int i; float soma_b1=0,soma_b2=0,soma_b3=0,soma_b4=0 float media_b1=0,media_b2=0,media_b3=0,media_b4=0; for(i=0;i<NUM_MAX;i++){ printf("Entre com o nome do aluno: "); scanf("%s", Turma[i].nome); printf("Entre com a matrícula do aluno: "); scanf("%s", Turma[i].matricula); printf("Entre com a nota do bimestre 1: "); scanf("%f", &Turma[i].b1); printf("Entre com a nota do bimestre 2: "); scanf("%f", &Turma[i].b2); printf("Entre com a nota do bimestre 3: "); scanf("%f", &Turma[i].b3); printf("Entre com a nota do bimestre 4: "); scanf("%f", &Turma[i].b4); } for(i=0;i<NUM_MAX;i++) { soma_b1 = (soma_b1+Turma[i].b1); /* usando media_b1 para soma acumulada */ soma_b2 = (soma_b2+Turma[i].b2); soma_b3 = (soma_b3+Turma[i].b3); soma_b4 = (soma_b4+Turma[i].b4); } media_b1 = (media_b1/NUM_MAX); media_b2 = (media_b2/NUM_MAX); media_b3 = (media_b3/NUM_MAX); media_b4 = (media_b4/NUM_MAX); printf("A media do B1 => %.2f\n",media_b1); printf("A media do B2 => %.2f\n",media_b2); printf("A media do B3 => %.2f\n",media_b3); printf("A media do B4 => %.2f\n",media_b4); return 0; }5. Repensar a estrutura TAluno para que as notas bimestrais sejam representadas como um vetor de floats. Fazer um código para calcular a média anual de cada aluno. Armazenar as médias anuais da turma em um vetor de floats.
solução Ex. 5 #include <stdio.h> #define NUM_MAX 3 struct TAluno { char nome[30]; char matricula[11]; float b[4]; } Turma[NUM_MAX]; void print_aluno(struct TAluno aux) { printf("Nome -> %s\n", aux.nome); printf("Matrícula -> %s\n", aux.matricula); printf("Bimestre 1 -> %f\n", aux.b[0]); printf("Bimestre 2 -> %f\n", aux.b[1]); printf("Bimestre 3 -> %f\n", aux.b[2]); printf("Bimestre 4 -> %f\n", aux.b[3]); } main() { int i,j; float media[NUM_MAX]={0,0,0}; for(i=0;i<NUM_MAX;i++) { printf("Entre com o nome do aluno\n"); scanf("%s", Turma[i].nome); printf("Entre com a matrícula do aluno\n"); scanf("%s", Turma[i].matricula); for(j=0;j<4;j++) { printf("Entre com a nota do bimestre %d\n", j+1); scanf("%f", &Turma[i].b[j]); } } /* calculo das médias bimestrais da turma */ /* separado do primeiro for para caracterizar a diferença de entrada de dados do processamento ... */ for(i=0;i<NUM_MAX;i++) { for(j=0;j<4;j++) media[i]=media[i]+Turma[i].b[j]; /* usando media_b1 para soma acumulada */ media[i]=media[i]/4; } }Copiando Estruturas
O exemplo a seguir demonstra como se pode copiar uma variável struct para outra do mesmo tipo.#include <stdio.h> struct THoras{ int hora; int minuto; int segundo; }; struct THoras Ontem = {2,10,57}; void main() { struct THoras Hoje; Hoje = Ontem; printf("Hora hoje = %d, Minuto hoje = %d e Segundo hoje %d\n", Hoje.hora, Hoje.minuto, Hoje.segundo); }Estruturas dentro de estruturas
Vamos ver um exemplo com estruturas definidas dentro de estruturas:
#include <stdio.h> struct TEndereco{ char rua[50]; char numero[10]; }; struct TCidadao{ char nome[50]; char cpf[20]; struct TEndereco endereco; int num_filhos; }; void main() { struct TCidadao Cidadao; printf("Entre com o nome\n"); scanf ("%s",Cidadao.nome); printf("Entre com o cpf\n"); scanf ("%s",Cidadao.cpf); printf("Entre a rua\n"); scanf ("%s",Cidadao.endereco.rua); printf("Entre a numero\n"); scanf ("%s",Cidadao.endereco.numero); printf("Entre com o número de filhos\n"); scanf ("%d",&Cidadao.num_filhos); }Exercício
- Faça um código adicional para imprimir o conteúdo lido na estrutura.
solução #include <stdio.h> struct TEndereco{ char rua[50]; char numero[10]; }; struct TCidadao{ char nome[50]; char cpf[20]; struct TEndereco endereco; int num_filhos; }; void print_cidadao(struct TCidadao aux) { printf("Nome: %s - CPF: %s\n", aux.nome, aux.cpf); printf ("Rua %s Número %s\n", aux.endereco.rua, aux.endereco.numero); printf("Numero de filhos %d\n", aux.num_filhos); } int main(void){ struct TCidadao Cidadao; printf("Entre com o nome\n"); scanf ("%s",Cidadao.nome); getchar(); printf("Entre com o cpf\n"); scanf ("%s",Cidadao.cpf); getchar(); printf("Entre a rua\n"); scanf ("%s",Cidadao.endereco.rua); getchar(); printf("Entre a numero\n"); scanf ("%s",Cidadao.endereco.numero); getchar(); printf("Entre com o número de filhos\n"); scanf ("%d",&Cidadao.num_filhos); print_cidadao(Cidadao); return 0; }Iniciando structs na definição
Como toda variável, é possível dar valores para uma variável do tipo struct definida no programa:
#include <stdio.h> struct TEndereco{ char rua[50]; char numero[10]; }; struct TCidadao{ char nome[50]; char cpf[20]; struct TEndereco endereco; int num_filhos; }; void main() { struct TCidadao Cidadao = {"Maria", "42342342234", {"Rua AlfaBeta","145"}, 5; }; printf("Rua do cidadao = %s\n", Cidadao.endereco.rua); }Passando estruturas como parâmetro e retornando estruturas
Se não for usado o operador "&" , um parâmetro que é estrutura será passado por cópia. Não apresentaremos agora a passagem por endereço pois necessita do conceita de ponteiro. Observe o exercício abaixo.
#include <stdio.h> struct TEndereco{ char rua[50]; char numero[10]; }; struct TCidadao{ char nome[50]; char cpf[20]; struct TEndereco endereco; int num_filhos; }; void print_struct (struct TCidadao aux) { printf("nome=%s cpf=%s\n", aux.nome, aux.cpf); printf("endereço inicial do aux %p\n", &aux); } void main() { struct TCidadao Cidadao; printf("Entre com o nome\n"); scanf ("%s",Cidadao.nome); printf("Entre com o cpf\n"); scanf ("%s",Cidadao.cpf); printf("Entre a rua\n"); scanf ("%s",Cidadao.endereco.rua); printf("Entre a numero\n"); scanf ("%s",Cidadao.endereco.numero); printf("Entre com o número de filhos\n"); scanf ("%d",&Cidadao.num_filhos); print_struct(Cidadao); printf("endereço inicial do Cidadao %p\n", &Cidadao); }O que podemos concluir com os endereços que foram mostrados??? Vamos a mais um exemplo.#include <stdio.h> struct TEndereco{ char rua[50]; char numero[10]; }; struct TCidadao{ char nome[50]; char cpf[20]; struct TEndereco endereco; int num_filhos; }; struct TCidadao ler_struct() { struct TCidadao aux; printf("Entre com o nome\n"); scanf ("%s",aux.nome); printf("Entre com o cpf\n"); scanf ("%s",aux.cpf); printf("Entre a rua\n"); scanf ("%s",aux.endereco.rua); printf("Entre a numero\n"); scanf ("%s",aux.endereco.numero); printf("Entre com o número de filhos\n"); scanf ("%d",&aux.num_filhos); return aux; } void print_struct (struct TCidadao aux) { printf("nome=%s cpf=%s\n", aux.nome, aux.cpf); printf("endereço inicial do aux %p\n", &aux); } void main() { struct TCidadao Cidadao; Cidadao = ler_struct(); print_struct(Cidadao); printf("endereço inicial do Cidadao %p\n", &Cidadao); }Aplicação de estruturas - Representação de números complexos
Um número complexo possui dois componentes reais que podem ser representados por duas variáveis float ou double. Observe que a declaração separada destes componentes prejudica a legibilidade do código e a construção de algoritmos eficientes para o tratamento destes números. Na sequência apresentamos exercícios que representam números complexos em estruturas.
- Implementar uma estrutura que permita representar um número complexo no formato retangular. Em adição, implemente uma função que permita somar dois números complexos retornando um número complexo com o valor da soma.
Solução Ex. 1 #include <stdio.h> struct tcomplexo { float x; /* parte real */ float y; /* parte imaginária */ }; struct tcomplexo add_complex(struct tcomplexo num_A, struct tcomplexo num_B) { struct tcomplexo temp; temp.x = num_A.x + num_B.x; temp.y = num_A.y + num_B.y; return temp; } int main(void) { struct tcomplexo num_1, num_2, num_3; num_1.x = 1.5; num_1.y = 2.5; num_2.x = 3.5; num_2.y = 1.5; num_3 = add_complex(num_1, num_2); /* implementar aqui m printf para mostrar o valor de num_3...*/ return 0; }- Implementar uma função que retorna o quadrante de um número complexo. O quadrante será um número inteiro 1, 2, 3 ou 4. Caso o número seja (0,0) retornar 0. Caso esteja sobre o eixo x retornar 5 e caso esteja sobre o eixo y retornar 6.
- Implementar uma função que retorne o módulo de um número complexo.
- Observação: Quando utilizar a biblioteca matemática [[<math.h>]] deve-se compilar o código com a opção -lm. Por exemplo: gcc -o arquivo arquivo.c -lm
Solução Ex. 2 #include <stdio.h> #include <math.h> struct tcomplexo { float x; float y; }; float calc_mod_complex(struct tcomplexo num_A) { float temp; temp = sqrtf(num_A.x*num_A.x + num_A.y * num_A.y); return temp; } main() { struct tcomplexo num_1; float result_mod; num_1.x = 1.5; num_1.y = 2.5; result_mod = calc_mod_complex(num_1); }- Implementar um programa que cria duas matrizes 2X2 de números complexos no formato retangular. Adicionalmente, implementar uma função para somar estas matrizes. Reusar a função de soma de número já implementada.
Solução Ex. 3 #include <stdio.h> #include <math.h> #define NUM_LIN 2 #define NUM_LIN 2 #define NUM_COL 2 struct tcomplexo { float x; float y; }; struct tcomplexo add_complex(struct tcomplexo num_A, struct tcomplexo num_B) { struct tcomplexo temp; temp.x = num_A.x + num_B.x; temp.y = num_A.y + num_B.y; return temp; } void add_mat_complex(struct tcomplexo mat_A[NUM_LIN][NUM_COL],struct tcomplexo mat_B[NUM_LIN][NUM_COL], struct tcomplexo mat_C[NUM_LIN][NUM_COL]) { int i,j; for (i=0;i<NUM_LIN;i++) for (j=0;j<NUM_COL;j++) mat_C[i][j]=add_complex(mat_A[i][j], mat_B[i][j]); } int main(void) { struct tcomplexo mat1[NUM_LIN][NUM_COL]={ {{.x=2.5,.y=2.7,}, {.x=1.5,.y=2.3,}}, {{.x=1.9,.y=2.6,}, {.x=3.5,.y=7.3,}} }, mat2[NUM_LIN][NUM_COL]={ {{.x=4.5,.y=2.8,}, {.x=1.6,.y=8.3,}}, {{.x=0.9,.y=2.9,}, {.x=7.5,.y=4.3,}} }, mat3[NUM_LIN][NUM_COL]; add_mat_complex(mat1,mat2,mat3); /* fazer função para imprimir matriz complexa... */ }- Implementar uma função converte_para_polar que recebe como parâmetro um número complexo na forma retangular (uma struct). A função deve retornar uma struct contendo o número complexo na forma polar.Usar as funções sqrt[1] e atan [2] da biblioteca matemática. Como converter:
- ou
Solução 4 #include <math.h> struct TComplexoRet { float x,y; }; struct TComplexoPolar { float mod,ang; }; struct TComplexoPolar convert_polar(struct TComplexoRet a) { struct TComplexoPolar aux; aux.mod = sqrtf(powf(a.x,2)+powf(a.y,2)); aux.ang = atan(a.y/a.x); return aux; } main() { struct TComplexoRet w; struct TComplexoPolar y; w.x = 11.5; w.y = 4.6; y = convert_polar(w); }- Implementar uma função que retorne a multiplicação de dois números complexos fornecidos como parâmetro.
Solução 5 //Autor : Victor Cesconetto De Pieri #include <stdio.h> #include <math.h> struct tcomplexo { float x; float y; }; float calc_num_imag(struct tcomplexo num_A, struct tcomplexo num_B) { float temp_imag = num_A.x * num_B.y + num_A.y * num_B.x; return temp_imag; } float calc_num_real(struct tcomplexo num_A, struct tcomplexo num_B) { float temp_real = num_A.x * num_B.x + num_A.y * num_B.y * (-1); return temp_real; } int main() { struct tcomplexo num_1; struct tcomplexo num_2; float real, imag; num_1.x = 2.5; num_1.y = 1; num_2.x = 2.5; num_2.y = 1; real = calc_num_real(num_1, num_2); imag = calc_num_imag(num_1, num_2); printf("Resultado : %f + %fi\n", real, imag); }Aplicação no Controle de Acesso
O exemplo a seguir implementa uma parte do programa de controle de acesso usando estruturas. Neste exemplo a tabela de usuários já vem inicializada nos campos UserID e Senha. A função strcmp da BIBLIOTECA DO C para comparação de strings. Ela retorna 0 caso as strings a serem comparadas sejam iguais. Note que deve ser incluído string.h
#include <stdio.h> #include <string.h> /**********************************************/ /***PROGRAMA DE CONTROLE DE ACESSO**/ /**********************************************/ /** VARIÁVEIS GLOBAIS DESTE MÓDULO ****/ struct TRegistroUsuario { char UserId[10]; char Senha[10]; }; /* Tabela de Usuários */ struct TRegistroUsuario TabelaUsuarios[4] = { {"joao","abcd"}, {"maria","xxxx"}, {"jose","yyyy"}, {"lara","zzzz"}, }; char userID[20]; /** FUNÇÔES DESTE MÓDULO ****/ void mostrar_menu_entrada_usuario() { printf("*******************************\n"); printf("Entre com o seu USERID para ter acesso\n"); printf("*******************************\n"); } /** Função que implementa as tarefas do administrador **/ void administrar() { } /** Função que valida um usuário e abre a porta **/ void tratar_usuario() { char senha[10]; int userEncontrado=1; int i; /* Loop para encontrar o usuário na tabela. Ao final do loop a variavel i conterá o índice do usuário (menos 1)(se ele estiver na tabela */ for (i=0;i<4 && userEncontrado; i++) { if( strcmp(userID, TabelaUsuarios[i].UserId)==0) userEncontrado=0; } /* se usuário encontrado abre a porta */ if (userEncontrado==0) { printf("Bom dia %s! Entre com a senha\n", userID); scanf("%s",senha); i--; /* o indice do sujeito é i-1 */ if(strcmp(senha,TabelaUsuarios[i].Senha)==0) printf("Abrir porta!!!\n"); else printf("Senha Inválida\n"); } } void main() { for(;;) { mostrar_menu_entrada_usuario(); scanf("%s",userID); if (strcmp(userID, "admin")==0) { administrar(); } else { tratar_usuario(); } } }Exercícios:
- Implementar um contador de acesso que permita bloquear o usuário após 3 tentativas seguidas. Note que caso o usuário acerte a senha, este contador deverá ser zerado.
Solução - Exercício 01 #include <stdio.h> #include <string.h> struct TRegistroUsuario { char UserId[10]; char Senha[10]; int contador; }; struct TRegistroUsuario TabelaUsuarios[4] = { {"joao","abcd",0}, {"maria","xxxx",0}, {"jose","yyyy",0}, {"lara","zzzz",0}, }; void tratar_usuario(char userid[20]) { char senha[10]; int userEncontrado=1; int i; for (i=0;i<4 && userEncontrado; i++) { if( strcmp(userid, TabelaUsuarios[i].UserId)==0) userEncontrado=0; } if (userEncontrado==0) {//se o usuario for encontrado começa-se o tratamento da senha i--; if (TabelaUsuarios[i].contador<3){ printf("Bom dia %s! Entre com a senha\n", userid); scanf("%s",senha); if(strcmp(senha,TabelaUsuarios[i].Senha)==0) { printf("Abrir porta!!!\n"); TabelaUsuarios[i].contador=0; } else { TabelaUsuarios[i].contador++; printf("Senha invalida\n"); printf("Tentativas restantes %d\n", 3-TabelaUsuarios[i].contador); if (TabelaUsuarios[i].contador==3) printf("%s seu userId foi bloqueado!!!!\n", TabelaUsuarios[i].UserId); } } else { printf("Usuário bloqueado\n"); } } else { printf("Usuário não encontrado\n"); } } int main(){ char userID[20]; for(;;) { printf("Entre com o seu USERID para ter acesso\n"); scanf("%s",userID); tratar_usuario(userID); } }
- Implementar uma funcionalidade do administrador para desbloquear o usuário bloqueado.
Solução - Exercício 02 #include <stdio.h> #include <string.h> /**********************************************/ /*** PROGRAMA DE CONTROLE DE ACESSO **/ /** Autor: Turma ENG.TELECOM - 2013.1 */ /**********************************************/ /** VARIÁVEIS GLOBAIS DESTE MÓDULO ****/ struct TRegistroUsuario { char UserId[10]; char Senha[10]; int contador; }; /* Tabela de Usuários */ struct TRegistroUsuario TabelaUsuarios[4] = { {"joao","abcd",0}, {"maria","xxxx",0}, {"jose","yyyy",0}, {"lara","zzzz",0}, }; char userID[20]; /** FUNÇÔES DESTE MÓDULO ****/ void mostrar_menu_entrada_usuario() { printf("*******************************\n"); printf("Entre com o seu USERID para ter acesso\n"); printf("*******************************\n"); } /** Função que implementa as tarefas do administrador **/ void administrar() { char aux_senha[10]; int userEncontrado=1; int i; printf("MODO ADMIN!!!! \n"); printf("Entre com a senha do admin \n"); scanf ("%s", aux_senha); if(strcmp(aux_senha,"123456")==0) { /* senha valida do admin - agora entre com userid a ser desbloqueado */ printf("Entre com userdID a ser desbloqueado\n"); scanf("%s",userID); for (i=0;i<4 && userEncontrado; i++) { if( strcmp(userID, TabelaUsuarios[i].UserId)==0) userEncontrado=0; } if (userEncontrado==0) { i--; TabelaUsuarios[i].contador=0; printf("ATENÇÃO: o usuário %s foi desbloqueado!\n", TabelaUsuarios[i].UserId); } } } /** Função que valida um usuário e abre a porta **/ void tratar_usuario() { char senha[10]; int userEncontrado=1; int i; /* Loop para encontrar o usuário na tabela. Ao final do loop a variavel i conterá o índice do usuário (se ele estiver na tabela */ for (i=0;i<4 && userEncontrado; i++) { if( strcmp(userID, TabelaUsuarios[i].UserId)==0) userEncontrado=0; } /* se usuário encontrado abre a porta */ if (userEncontrado==0) { i--; /* o indice do sujeito é i-1 */ if (TabelaUsuarios[i].contador<3){ printf("Bom dia %s! Entre com a senha\n", userID); scanf("%s",senha); if(strcmp(senha,TabelaUsuarios[i].Senha)==0) { printf("Abrir porta!!!\n"); TabelaUsuarios[i].contador=0; } else { TabelaUsuarios[i].contador++; printf("Senha Inválida\n"); printf("Tentativas restantes %d\n", 3-TabelaUsuarios[i].contador); if (TabelaUsuarios[i].contador==3) printf("ATENÇÃO usuário %s - fale com o ADMINISTRADOR DO SISTEMA - SEU LOGIN FOI BLOQUEADO!\n", TabelaUsuarios[i].UserId); } } else { printf("Usuário bloqueado\n"); } } else { printf("Usuário não encontrado\n"); } } void main() { for(;;) { mostrar_menu_entrada_usuario(); scanf("%s",userID); if (strcmp(userID, "admin")==0) { administrar(); } else { tratar_usuario(); } } }
- No programa de controle de senha inserir um campo na estrutura do usuário de forma a acomodar uma mensagem de boas vindas particularizada para cada usuário. A mensagem "DEFAULT" é Bom dia!
Solucão - Exercício 03 #include <stdio.h> #include <string.h> struct TRegistroUsuario { char UserId[10]; char Senha[10]; int contador; char mensagem[20]; }; struct TRegistroUsuario TabelaUsuarios[4] = { {"joao","abcd",0,"Bom dia João"}, {"maria","xxxx",0,"Bom dia Maria"}, {"jose","yyyy",0,"Bom dia José"}, {"lara","zzzz",0,"Bom dia Lara"}, }; void tratar_usuario(char userid[20]) { char senha[10]; int userEncontrado=1; int i; for (i=0;i<4 && userEncontrado; i++) { if( strcmp(userid, TabelaUsuarios[i].UserId)==0) userEncontrado=0; } if (userEncontrado==0) {//se o usuario for encontrado começa-se o tratamento da senha i--; if (TabelaUsuarios[i].contador<3){ printf("%s! Entre com a senha\n",TabelaUsuarios[i].mensagem); scanf("%s",senha); if(strcmp(senha,TabelaUsuarios[i].Senha)==0) { printf("Abrir porta!!!\n"); TabelaUsuarios[i].contador=0; } else { TabelaUsuarios[i].contador++; printf("Senha invalida\n"); printf("Tentativas restantes %d\n", 3-TabelaUsuarios[i].contador); if (TabelaUsuarios[i].contador==3) printf("%s seu userId foi bloqueado!!!!\n", TabelaUsuarios[i].UserId); } } else { printf("Usuário bloqueado\n"); } } else { printf("Usuário não encontrado\n"); } } int main(){ char userID[20]; for(;;) { printf("Entre com o seu USERID para ter acesso\n"); scanf("%s",userID); tratar_usuario(userID); } } }
- Implementar na função administrar a inserção da mensagem no exercício anterior.
Solução - Exercício 04 #include <stdio.h> #include <string.h> struct TRegistroUsuario { char UserId[10]; char Senha[10]; int contador; char mensagem[20]; }; struct TRegistroUsuario TabelaUsuarios[4] = { {"joao","abcd",0,"Bom dia João"}, {"maria","xxxx",0,"Bom dia Maria"}, {"jose","yyyy",0,"Bom dia José"}, {"lara","zzzz",0,"Bom dia Lara"}, }; void tratar_usuario(char userid[20]) { char senha[10]; int userEncontrado=1; int i; for (i=0;i<4 && userEncontrado; i++) { if( strcmp(userid, TabelaUsuarios[i].UserId)==0) userEncontrado=0; } if (userEncontrado==0) {//se o usuario for encontrado começa-se o tratamento da senha i--; if (TabelaUsuarios[i].contador<3){ printf("%s! Entre com a senha\n",TabelaUsuarios[i].mensagem); scanf("%s",senha); if(strcmp(senha,TabelaUsuarios[i].Senha)==0) { printf("Abrir porta!!!\n"); TabelaUsuarios[i].contador=0; } else { TabelaUsuarios[i].contador++; printf("Senha invalida\n"); printf("Tentativas restantes %d\n", 3-TabelaUsuarios[i].contador); if (TabelaUsuarios[i].contador==3) printf("%s seu userId foi bloqueado!!!!\n", TabelaUsuarios[i].UserId); } } else { printf("Usuário bloqueado\n"); } } else { printf("Usuário não encontrado\n"); } } void administrar() { char aux_senha[10]; char userID[20]; char novamensagem[20]; int userEncontrado=1; int i; int select; printf("MODO ADMIN!!!! \n"); printf("Entre com a senha do admin \n"); scanf ("%s", aux_senha); if(strcmp(aux_senha,"123456")==0) { /* senha valida do admin - agora entre com userid a ser desbloqueado */ printf("Voce deseja desbloquear usuario - 1\nVoce deseja mudar a mensagem de boas vindas - 2\n"); scanf("%d",&select); if(select==1){ printf("Entre com userdID a ser desbloqueado\n"); scanf("%s",userID); for (i=0;i<4 && userEncontrado; i++) { if( strcmp(userID, TabelaUsuarios[i].UserId)==0) userEncontrado=0; } if (userEncontrado==0) { i--; TabelaUsuarios[i].contador=0; printf("ATENÇÃO: o usuário %s foi desbloqueado!\n", TabelaUsuarios[i].UserId); } }else{ printf("Entre com userdID a ser trocado a mensagem\n"); scanf("%s",userID); for (i=0;i<4 && userEncontrado; i++) { if( strcmp(userID, TabelaUsuarios[i].UserId)==0) userEncontrado=0; } if (userEncontrado==0) { i--; printf("Digite uma nova mensagem de boas vindas para %s :\n",TabelaUsuarios[i].UserId); scanf("%s",novamensagem); printf("%s\n",novamensagem); strcpy(TabelaUsuarios[i].mensagem,novamensagem); printf("%s\n",TabelaUsuarios[i].mensagem); printf("Mensagem atualizada com sucesso\n"); } } } } int main() { char userID[20]; for(;;) { printf("Entre com o seu USERID para ter acesso\n"); scanf("%s",userID); if (strcmp(userID, "admin")==0) { administrar(); } else { tratar_usuario(userID); } } }Referências
https://www.geeksforgeeks.org/memory-layout-of-c-program/
https://docs.cs50.net/2017/fall/notes/5/lecture5.html#data-structures
http://www.mathwarehouse.com/programming/passing-by-value-vs-by-reference-visual-explanation.php