Ir ao conteúdo
  • Cadastre-se

C Como editar um subconjunto de uma struct já armazenada?


Madson Smitt

Posts recomendados

Boa/bom noite/tarde/dia, pessoal.

Gostaria de saber como posso alterar os dados de um subconjunto da struct já armazenado...

Por exemblo: O usuário entrou com varios dados na struct que montei e, um desses subconjuntos, é o nome do contato de quem ele deseja armazenar. Que é um vetor de char. Gostaria de saber se tem como eu mexer nesses vetores de char já armazenados para criar uma opção no programa de listar os nomes que comecem com tal letra de preferência do usuário (EX: ele quer que apareçam os contatos que comecem com a letra M, assim eu listo todos os contatos que contém M no INICIO do primeiro nome).

 

Segue o code: 

#include <stdlib.h>
#include <stdio.h>
#include <conio.h>

struct agenda{
	char PrimeiroNome[15];
	char UltimoNome[15];
	char ddd[6];
	char telefone[12];
};
void NomeTel(struct agenda *NT){
	printf("\nDigite o primeiro nome do contato: ");
	scanf("%14s", NT->PrimeiroNome);
	printf("Digite o ultimo nome do contato: ");
	scanf("%14s", NT->UltimoNome);
	printf("Digite o DDD do contato: ");
	scanf("%5s", NT->ddd);
	printf("Digite o numero do contato: ");
	scanf("%11s", NT->telefone);
}
void PrintContatos(struct agenda *x){
	printf("\n\nContato:");
	printf("\nPrimeiro nome do contato: %s", x->PrimeiroNome);
	printf("\nUltimo nome do contato: %s", x->UltimoNome);
	printf("\nNumero do contato: (%s) %s", x->ddd, x->telefone);
	printf("\n\n");
}
void PrimeiraParte(int *aux){
	system("cls");
	printf("\t\t\t\tOpcoes disponiveis na agenda: \n");
	printf("\n");
	printf("Adicionar um contato a agenda (1)\n");
	printf("\nListar contatos da agenda (2)\n");
	printf("\nSair da agenda (3)\n");
	printf("\nDigite o numero, de uma das opções listadas, para realizar uma acao: ");
	scanf("%i", aux);
}

int main(){
	int opinici, numlistar, numadc = 0, sublistar, *aux, sair = 0, contador = 0, i = 0, auxcont, auxnumlistar;
	struct agenda contatin[20];
	printf("\t\t\t\t\tBem-vindo a agenda!\n");
	printf("\n");
	printf("Tecle ENTER para ir a agenda...");
	getchar();
	while(sair == 0){
		aux = &opinici;
		PrimeiraParte(aux);
	switch(opinici){
		case 1:
			system("cls");
			printf("\t\t\t\t\tAdicione um contato a sua agenda: \n");
			printf("\n");
			do{
			NomeTel(&contatin[contador]);
					printf("\nContato armazenado!\n");
			printf("\n");
			do{
			printf("\nDeseja armazenar mais algum contato? Digite 1 para SIM e 2 para NAO: ");
			scanf("%i", &numadc);
			}while(numadc < 1 || numadc > 2);
			contador++;
	}while(numadc != 2);
			printf("\nTecle QUALQUER TECLA para continuar com a agenda e voltar ao menu inicial...");
			getche();
			system("cls");
		break;
		
			case 2:
				system("cls");
				printf("\t\t\t\t\tLista de Contatos: \n");
				printf("\n");
				i = 0;
				auxcont = contador;
				while(i < auxcont){
					printf("Codigo do contato: %i", i);
					PrintContatos(&contatin[i]);
					i++;
				}
				printf("\n\n");
				printf("Acoes disponiveis: \n");
				printf("\n");
				printf("\tEditar contato (1)\n");
				printf("\tApagar contato (2)\n");
				printf("\tVoltar ao menu inicial (3)\n");
				printf("\n");
				do{
				printf("Digite o numero, de uma das opções listadas, para realizar uma acao: ");
				scanf("%i", &sublistar);
				if(sublistar == 1 && contador == 0 || sublistar == 2 && contador == 0){
					printf("\nNenhum contato na agenda para fazer alteracoes!\n");
					break;
				}
				if(sublistar == 1){
					printf("\n");
					do{
					printf("Digite o codigo do contato o qual deseja editar: ");
					scanf("%i", &numlistar);
				}while(numlistar < (contador-contador) || numlistar >= contador);
					printf("\nDigite as novas informações do contato para edita-lo totalmente:");
					NomeTel(&contatin[numlistar]);
					printf("\nDados alterados com sucesso!\n");
				}
				if(sublistar == 2){
					printf("\n");
					do{
					printf("Digite o codigo do contato o qual deseja apagar: ");
					scanf("%i", &numlistar);
				}while(numlistar < (contador-contador) || numlistar >= contador);					
					auxnumlistar = 0; 
                    if(contador == 1){
                        contatin[numlistar] = contatin[numlistar+1];
                    }
                    if(contador > 1){
                        while(auxnumlistar < contador){ 
                            contatin[numlistar] = contatin[numlistar+1];
                            numlistar++; 
                            auxnumlistar++; 
                        }
                    }
                contador--;
					printf("\nAs informações do contato foram apagadas!");
					printf("\n");
				}
			}while(sublistar < 1 || sublistar > 3);
				printf("\nTecle QUALQUER TELCA para continuar com a agenda e voltar ao menu inicial...");
				getche();
				system("cls");
		break;
				
				case 3:
					system("cls");
					printf("\t\t\t\t\t************************\n");
					printf("\t\t\t\t\t***");
					printf(" AGENDA ENCERRADA ***\n");
					printf("\t\t\t\t\t************************\n");
					sair = 1;
		break;
					
					default:
						printf("\n\n");
						printf("Opcao invalida!\nDigite uma das opções listadas acima!\n");
						printf("Pressione qualquer tecla...");
						getche();
						system("cls");
				}
			}
	system("pause");
	return 0;
}

 

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

Olá

 

Você pode acessar esses valores da mesma maneira que usou em scanf() por exemplo.  Não há diferença alguma. 

    char     PrimeiroNome[15];
    char     UltimoNome[15];

PrimeiroNome é um char[15];  O primeiro caracter deve estar em PrmeiroNome[0] e é claro um char.

char    inicial = 'C';
if ( PrimeiroNome[0] == inicial )
{
    // este comeca com a inicial desejada
}

Ou talvez 

if ( toupper(PrimeiroNome[0])  == inicial )
{
    // este comeca com a inicial desejada
}

Para não ter que se preocupar com maiúsculas e minúsculas

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

@arfneto

Em 24/10/2019 às 18:27, arfneto disse:

Olá

 

Você pode acessar esses valores da mesma maneira que usou em scanf() por exemplo.  Não há diferença alguma. 


    char     PrimeiroNome[15];
    char     UltimoNome[15];

PrimeiroNome é um char[15];  O primeiro caracter deve estar em PrmeiroNome[0] e é claro um char.


char    inicial = 'C';
if ( PrimeiroNome[0] == inicial )
{
    // este comeca com a inicial desejada
}

Ou talvez 


if ( toupper(PrimeiroNome[0])  == inicial )
{
    // este comeca com a inicial desejada
}

Para não ter que se preocupar com maiúsculas e minúsculas

 

Valeuuu, consegui fazer da seguinte maneira:

if(sublistar == 3){
					system("cls");
					printf("\t\t\t\t\tListar contatos pela primeira letra do nome: \n");
					printf("\n");
					printf("Digite uma letra, de sua preferência, para pesquisar \nnomes de contatos que comecem com essa letra: ");
					scanf("%1s", letra);
					printf("\n");
					printf("Contatos Encontrados:   ");
					listarpornome = 1;
					for(i = 0; i < contador; i++){
					if((&*contatin)[i].PrimeiroNome[0] == letra[0]){
						printf("%i. %s %s\n\t\t\t", listarpornome, (&*contatin)[i].PrimeiroNome, (&*contatin)[i].UltimoNome);
						listarpornome++;
					}
				}
				}

 

Link para o comentário
Compartilhar em outros sites

13 horas atrás, Madson Smitt disse:

Verdade, pensando assim não faz sentido...

tentei só deixando "x" e consegui... Deixar &* pode dar algum problema referente ao programa achar os valores? ou só atrapalha no sentido mesmo?

 

Não é que atrapalhe. Veja assim: você sempre pode escrever (x) ou (1 + x - 1) ou (1*x) só não faz isso porque não faz diferença. 

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

@Madson Smitt boa tarde.

 

15 horas atrás, Madson Smitt disse:

Deixar &* pode dar algum problema referente ao programa achar os valores?

 

Jamais! É muito menos comum que  desreferência e referência índices de vetores. E.i.: &array[11]. É interessante também porque se faz pouco juízo de casos comuns se comparado a casos inusitados (pelo menos para mim). Observe que ...

int minha_matriz [10];

scanf (" %d" , &minha_matriz [0]); /* É  comum e difuso em livros e blogs         */
scanf (" %d" , &*minha_matriz   ); /* É ~comum, porém são a mesma coisa           */

/* ambos são igualmente redundantes e ingenuos. Mesmo nos casos em que
   o índice no vetor é diferente de 0. Observe ... */


scanf (" %d" , minha_matriz + 9);  /* É comum e conceitualmente claro             */

/* Já ... */
scanf (" %d" , &*(minha_matriz + 9)); /* É incomum e conceitualmente redundante   */
scanf (" %d" , &minha_matriz [9]); /* É comum e conceitualmente aceito            */
/* mesmo envolvendo uma etapa sem necessidade também                              */

Obrigado. 

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

5 horas atrás, Mauro Britivaldo disse:

@Madson Smitt boa tarde.

 

 

Jamais! É muito menos comum que  desreferência e referência índices de vetores. E.i.: &array[11]. É interessante também porque se faz pouco juízo de casos comuns se comparado a casos inusitados (pelo menos para mim). Observe que ...

Obrigado. 

 

Entendam que não vai dar problema simplesmente porque um é o inverso do outro, e

o inverso do inverso é a identidade

Ou em termos coloquiais o contrário do contrário dá do mesmo.

No caso do exemplo acima podia se acrescentar a esses

int minha_matriz [10];

scanf (" %d" , &minha_matriz [0]);     /* É  comum e difuso em livros e blogs         */
scanf (" %d" , &*minha_matriz );       /* É ~comum, porém são a mesma coisa           */

o simples:

scanf (" %d" , minha_matriz );         /* o simples, lembrando que para o %d scanf() 
                                          espera um endereco como argumento correspondente
                                          e entao o leitor tem que supor que minha_matriz
                                          seja algum tipo de ponteiro. Essa e a razao dos autores e
                                          profissionais escreverem muitas vezes &minha_matriz[0]: so
                                          para ficar mais claro. E esse uso pode impactar no tempo 
                                          de execucao
                                        */

Autores e profissionais muitas vezes escrevem &minha_matriz[0] apenas para deixar claro o que é a variável, no caso minha_matriz, sem que o leitor tenha que ir até a declaração, que nem sempre está na linha de cima...

Ao escrever &matriz[0] assim se entende que matriz é int[] e é uma boa coisa pra quem está lendo. Ao escrever só matriz fica algo vago e pode levar o leitor a ir até a declaração e perder um tempo.

Escrever &* por outro lado é como escrever x*x/x ao invés de x.

 

Veja esse resultado 

matriz[0]=27102019

[m = &*matriz] m=27102019

[m = &*matriz] m=27102019

[m = &matriz[0] m=27102019

[m = &*&*&*&*&*&*&*&*&*&*&*&*&*&*matriz] m=27102019

[m = &*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*matriz] m=27102019

[m =[100 pares de &*] m=27102019

mostrado por esse programa

#include    <stdio.h>
int    main(int argc, char** argv)
{
    int matriz[10];

    matriz[0] = 27102019;
    printf("\nmatriz[0]=%d\n", matriz[0]);

    int* m = &*matriz;
    printf("\n[m = &*matriz] m=%d\n", *m);

    m = matriz;
    printf("\n[m = &*matriz] m=%d\n", *m);

    m = &matriz[0];
    printf("\n[m = &matriz[0] m=%d\n", *m);

    m = &*&*&*&*&*&*&*&*&*&*&*&*&*&*matriz;
    printf("\n[m = &*&*&*&*&*&*&*&*&*&*&*&*&*&*matriz] m=%d\n", *m);

    m = &*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*matriz;
    printf("\n[m = &*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*matriz] m=%d\n", *m);

    m = &*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*\
&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*\
&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*\
&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*\
&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*\
            matriz;
    printf("\n[m =[100 pares de &*] m=%d\n", *m);   
    return 0;
}

Acho que deu pra entender. Não é uma maneira exótica de escrever, é só uma possibilidade sem razão.

O inverso de & é * O inverso de * é &

O inverso de * pode ser também / e muitos criticam C por essa ambiguidade.

Assim nesse código

    int x = 22;

    printf("\nx=%d\n", x);

    x = x / x * x;
    printf("x=%d\n", x);

    x = x / x * x / x * x;
    printf("x=%d\n", x);

    x = x / x * x / x * x / x * x / x * x;
    printf("x=%d\n", x);

Todos os printf() mostram 22.

 

No caso de matriz vs. &matriz[0] faz diferença? 


Sim. Veja o código gerado por um compilador moderno com opções padrão de geração de código, nesse caso Microsoft Visual Studio 16.3.6, para essas linhas de exemplo

ex-disasm-2.thumb.png.50a31e06334d4bf7a1f8fdc2beadbc66.png

 

E vai ver que o otimizador percebe os pares &* e descarta, mas para o caso de &matriz[0] ele gera o dobro de instruções, instruções similares, e assim vai levar o dobro de tempo para executar essas atribuições do exemplo

 

Minha sugestão: em resumo, esqueça isso. Só é divertido. 

 


 

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

1 hora atrás, arfneto disse:

Entendam que não vai dar problema simplesmente porque um é o inverso do outro, e

 

Concordo! Sim e não sejamos intencionalmente redundantes nesse e em outros assuntos.

 

1 hora atrás, arfneto disse:

Minha sugestão: em resumo, esqueça isso. Só é divertido. 

 

Discordo 😣 porque ... 

  1. você de todos não ignorou o fato é agora está sendo, sinceramente mais uma vez, prolixo;
  2. faz menos sentido ainda eu estender uma discussão para depois auto sugerir o seu fim.
  3. se internalizou a questão pormenores somente agora bom pra você, mas poderia muito bem ter resolvido por mensagem pessoal, já que a correção pública abre quase sempre novas discussões e abriu.

 

Enfim, só quis aproveitar o parenteses que foi aberto no tópico e elucidar um FATO igualmente desnecessário da sintaxe que de bom senso comente-se quase sempre por razões didáticas, ou seja, a clássica frase: "foi assim que vi no livro"

 

Obrigado.

 

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

20 horas atrás, Mauro Britivaldo disse:

prolixo

:D

 

Esse é um forum para iniciantes.

 

Então quando meu tempo admite e a questão também, procuro usar sempre o mesmo roteiro:

  • uma introdução, com um algoritmo ou referências históricas
  • um programa, inteiro, em C ou C++ --- não uso C# --- funcionando
  • em geral com uma demonstração da saída do programa primeiro porque eu acho que faz diferença em relação a umas linhas desconexas de código no caso de quem está de fato com uma dúvida.
  • um link para download do programa e às vezes com alguns arquivos de saída de outros testes
  • quando o tempo admite e faz sentido, discuto ou mostro soluções alternativas
  • às vezes discuto algum pormenor que acho que possa ser um aspecto interessante relacionado à dúvida original

Porque?

 

Acho que apenas porque era o que eu gostaria de ter tido a oportunidade de receber quando eu comecei a aprender essas coisas. Uma solução, uma justificativa, um exemplo ou um roteiro. E quem sabe tudo isso junto. E de graça? Nada mal teria sido. Continuo aprendendo e raramente recebo isso, no entanto :D  

  • Curtir 1
  • Obrigado 1
Link para o comentário
Compartilhar em outros sites

2 horas atrás, arfneto disse:

Acho que apenas porque era o que eu gostaria de ter tido a oportunidade de receber quando eu comecei a aprender essas coisas.

Eu também! comecei quando a internet não era internet e não tinha nada de útil para aprender a programar ;-;, mas ai e aprendi a linguagem de programação mais útil do mundo o inglês e "until this date, it's the more powerful tool I have".

 

Na minha opinião. os exemplos no fórum são muito bem vindos mesmo eu que já programo a uma longa data ainda me perco com muitas coisas (troquei de idioma e tudo parece estranho) já me beneficiei de muita coisa do fórum (foi assim que eu cheguei aqui).

  • Curtir 2
Link para o comentário
Compartilhar em outros sites

33 minutos atrás, KXSY disse:

Eu também! comecei quando a internet não era internet e não tinha nada de útil para aprender a programar ;-;, mas ai e aprendi a linguagem de programação mais útil do mundo o inglês e "until this date, it's the more powerful tool I have"

 

Quando eu comecei a programar, em um IBM/370-148 usando FORTRAN então não era mesmo época de muitos exemplos :D

  • Curtir 2
Link para o comentário
Compartilhar em outros sites

@arfneto

Em 27/10/2019 às 19:05, arfneto disse:

E vai ver que o otimizador percebe os pares &* e descarta, mas para o caso de &matriz[0] ele gera o dobro de instruções, instruções similares, e assim vai levar o dobro de tempo para executar essas atribuições do exemplo

Nunca que se passou pela minha cabeça que isso poderia dar algum tipo de lag no sistema. obrigado por me avisar. Vou tentar melhorar tendo isso em mente nos próximos códigos, para que eu não acabe sobrecarregando tudo. xD

adicionado 5 minutos depois

@Mauro Britivaldo

Em 27/10/2019 às 13:19, Mauro Britivaldo disse:

Jamais! É muito menos comum que  desreferência e referência índices de vetores. E.i.: &array[11]. É interessante também porque se faz pouco juízo de casos comuns se comparado a casos inusitados

 

Eu pensei que poderia ocorrer algum erro se eu colocassem somente o nome da váriavel, ex: minha_matriz.

Então na minha cabeça se passou que eu teria que mostrar o valor que estava contido no endereço da variável, ou seja, &*minha_matriz. Valeu por esclarecer que não vai haver erro na captação da varável. 

 

Link para o comentário
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisa ser um usuário para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...

Ebook grátis: Aprenda a ler resistores e capacitores!

EBOOK GRÁTIS!

CLIQUE AQUI E BAIXE AGORA MESMO!