Jump to content
thinkabout

Lista telefónica - Estruturas

Recommended Posts

thinkabout

Boas,

Estou com problemas no ponto e), eu consigo ver quem vive na mesma casa mas tenho muitas repetições.

O manel vive na mesma casa da manel.

O manel vive na mesma casa da maria.

O manel vive na mesma casa da ze.

O ze vive na mesma casa da ze.

O ze vive na mesma casa da maria.

O ze vive na mesma casa da manel.

O maria vive na mesma casa da

...

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/*
3. Pretende-se criar uma agenda para armazenar números de telefone (nome, rede e número).
a) Crie um tipo estruturado que lhe permita armazenar essa informação.
b) Declare uma tabela que lhe permita armazenar 100 números de telefones. A tabela deve ser
uma variável local da função main()
c) Desenvolva uma função que inicialize uma estrutura do tipo telefone. É passado como
argumento um ponteiro para a estrutura a inicializar. Os dados são fornecidos pelo utilizador.
d) Desenvolva uma função que liste todas as pessoas cujo telefone pertença a uma determinada
rede. A função recebe como argumentos um ponteiro para o início da tabela, o número de
elementos que esta contém e a indicação de qual a rede em causa.
e) Desenvolva uma função que descubra todas as pessoas que vivem na mesma casa. Considere
que duas pessoas vivem na mesma casa se tiverem o mesmo número de telefone;
f) Desenvolva uma função para retirar da tabela a informação relativa a uma pessoa cujo nome é
passado como parâmetro. Pode assumir que os nomes são únicos.
g) Criar um programa que inicialize tabela com informação sobre determinado número de
pessoas (o número de pessoas é introduzido através da linha de comando). A seguir deve
listar todas as pessoas que pertencem a uma determinada rede (cuja identificação também é
passado como argumento da linha de comando). Finalmente, o programa deve pedir ao
utilizador que introduza o nome de uma pessoa para ser retirada da tabela.

*/

struct agenda {
char nome[100];
int rede;
int numero;
};
typedef struct agenda contactos;

#define MAX 100
int total=0;

void imprime_contacto(contactos lista)
{
printf("Nome %s, rede %d, numero %d \n", lista.nome , lista.rede, lista.numero );
}

void escreve_todosrede(contactos lista[], int total , int rede)
{
int i;

for (i = 0; i < total; i++)
{
	if (rede == lista[i].rede)
	{
		imprime_contacto(lista[i]);
	}
}

}

void procura_mesmacasa(contactos lista[], int total )
{
int i,j;

for (i = 0; i < total; i++)
{
	for (j = 0; j  < total;  j++)
	{

		if (lista[i].numero == lista[j+1].numero)
		{
			printf("O %s vive na mesma casa que %s \n" , lista[i].nome, lista[j+1].nome);
		}
	}
}

}

contactos obtem_info()
{
contactos t; // Variável temporária do tipo struct 
printf("Nome: ");
scanf("%s", &t.nome);
fflush(stdin);
printf("rede ");
scanf("%d", &t.rede);
fflush(stdin);
printf("numero ");
scanf("%d", &(t.numero));
return t;
}

int adiciona_numero(contactos lista[] ,int total)
{
if(total >= MAX)
{
	puts("A lista telefonica esta cheia");
	return total;
}
else
{
	lista[total] = obtem_info();
	return total+1;
}
}

int menu()
{
int i;
puts("1 - Adiciona Contacto Novo");
puts("2 - Lista de contactos");
puts("3 - Lista Clientes da rede X");
puts("4 - Mostra Quem vive na mesma casa");
puts("5 - Terminar");
puts("Escolha uma opção: ");
do{
	scanf("%d", &i);
}while(i<1 || i>5);
return i;
}

int main()
{
contactos lista[MAX];
int i, total=0;

do {
	i = menu();
	switch(i){
	case 1: total = adiciona_numero(lista,total); break;
	//case 2: total = listatotal(lista,total); break;
	case 3: escreve_todosrede(lista,total,96); break;
	case 4: procura_mesmacasa(lista, total); break;
	}
} while(i != 5);
return 0;
}

e) Desenvolva uma função que descubra todas as pessoas que vivem na mesma casa. Considere

que duas pessoas vivem na mesma casa se tiverem o mesmo número de telefone;

void procura_mesmacasa(contactos lista[], int total )
{
int i,j;

for (i = 0; i < total; i++)
{
	for (j = 0; j  < total;  j++)
	{

		if (lista[i].numero == lista[j+1].numero)
		{
			printf("O %s vive na mesma casa que %s \n" , lista[i].nome, lista[j+1].nome);
		}
	}
}

}

Share this post


Link to post
Share on other sites
Rui Carlos

Cria um array auxiliar para marcares os elementos que já verificaste que vivem com outra pessoa.

Adicionalmente, no ciclo interior devias começar na posição i+1, para não repetires elementos.

void procura_mesmacasa(contactos lista[], int total )
{
       char *done = calloc(total, sizeof(char));  // array auxiliar, inicializado a 0
       int i,j;

       for (i = 0; i < total; i++)
       {
               if(done[i]==0) // esta posição ainda não foi processada
               {

                       for (j = i+1; j < total;  j++)  // não comeces no 0, começa logo no i+1, para evitar repetidos
                       {
                               if (lista[i].numero == lista[j].numero)
                               {
                                       printf("O %s vive na mesma casa que %s \n" , lista[i].nome, lista[j].nome);
                                       done[j] = 1; // já indicámos que j vive com outra pessoa, logo marca a posição j como processada
                               }
                       }
               }
       }
}

Share this post


Link to post
Share on other sites
thinkabout

Boas,

f) Desenvolva uma função para retirar da tabela a informação relativa a uma pessoa cujo nome é passado como parâmetro. Pode assumir que os nomes são únicos.

Isto já faz o que eu quero, contudo só se meter lá o nome a mão.

Chamo a função com

main()
{
char fulanox='z';
case 5: total = apagaX(lista,total,fulanox); break;
}


int apagaX(contactos lista[] ,int total,  char fulanoX)
{
   int i;

   for (i = 0; i < total; i++)
   {
       if ((strcmp ("ze",lista[i].nome) == 0))
       {
           puts("Encontrei o ze e vou o tirar da lista"); 
           lista[i] = lista[total];
           return total-1;
       }    
   }
   return total;
}

Contudo queria ser livre de mandar o nome logo para o fulanoX.

De forma a isto trabalhar

if ((strcmp (fulanoX,lista[i].nome) == 0))

Contudo obtenho os seguintes warnings.

warning C4047: 'function' : 'const char *' differs in levels of indirection from 'char'

warning C4024: 'strcmp' : different types for formal and actual parameter 1

Edited by thinkabout

Share this post


Link to post
Share on other sites
thinkabout

int main()
{
   contactos lista[MAX];
   char fulanoX[10]="x";

   int i, total=0;
   gets(fulanoX); // Testar a alinha f)
....
}

int apagaX(contactos lista[] ,int total,  char *fulanoX)

Se fizesse char *fulanoX ="ze" no main e depois no envio metesse &fulanoX[0].

Quando tentava mudar o fulanoX, isto estoirava.

http://stackoverflow.com/questions/1704407/what-is-the-difference-between-char-s-and-char-s-in-c

Edited by thinkabout

Share this post


Link to post
Share on other sites
Rui Carlos

Assumo que fulanoX é uma string e não um caracter, pelo que o seu tipo deverá ser char* (ou char[]). Até porque na lista nome é uma string.

Por que é que haverias de usar &fulanoX[0]? Isso é a mesma coisa que fulanoX.

Muda o main para algo como:

int main()
{
   char fulanox[10];
   ...
   fgets(fulanox, 9, stdin);
   ...
   apagaX(lista, total, fulanox);
}

Muda também a assinatura da função.

Share this post


Link to post
Share on other sites
thinkabout

Está-me a escapar algo o gajo recebe bem o nome do fulano, mas depois não faz a verificação correctamente.

Se fizer o main com gets funciona bem se fizer com fgets apesar de ele continuar na mesma a receber o nome do fulano, não acha a comparação.

int apagaX(contactos lista[] ,int total,  char *fulanoX)
{


int i;
printf("vou procurar o fulano %s", fulanoX);

for (i = 0; i < total; i++)
{
if ((strcmp (fulanoX,lista[i].nome) == 0))
{

O gajo mete para ali o '\n'

Edited by thinkabout

Share this post


Link to post
Share on other sites
HappyHippyHippo

sim, o fgets lê tambem a tecla ENTER que carregas:


int strlength = strlen(fulanoX);
if (fulanoX[strlength - 1] == '\n')
fulanoX[strlength - 1] = '\0'
[/Code]


IRC : sim, é algo que ainda existe >> #p@p

Share this post


Link to post
Share on other sites
PsySc0rpi0n

Sim, essa parte eu já tinha percebido.

Mas pelo que me explicaram, se tivermos uma variável tipo nome[4] e gravar lá "abc" usando fgets(nome, 4, stdin), a string fica "abc\0" e o '\n' fica no buffer do teclado.

Se fizer fgets(nome, 5, stdin), a string fica "abc\n\0" mas não é garantido... É esta parte que não percebi do que me explicaram...


Kurt Cobain - Grunge misses you

Nissan GT-R - beast killer

Share this post


Link to post
Share on other sites
HappyHippyHippo

a resposta está (quase sempre) no nome da função:

f     - de um stream
get  - ler uma
   s - string

estás a ler uma string, logo tem de ter o '\0' no final (de que maneira for)

se estas a dizer que o array dado à função só tem 4 elementos, então, no máximo, irá ler 3 elementos porque o '\0' tem que ser guardado

conclusão: o fgets lê o stream dado até :

- encontrar um '\n' (inclusivé)

- o stream não tiver mais elementos a serem lidos

- não haver mais espaço no array dado de modo a que seja sempre possível guardar o '\0' final da string


IRC : sim, é algo que ainda existe >> #p@p

Share this post


Link to post
Share on other sites
PsySc0rpi0n

Então porque é que isto|, se usar o nome "José", resulta em 5 e não em 4???? Estive a ver a manpage do strlen e ele exclui o '\0'!!!

|

|

V

#include <stdio.h>
#include <string.h>
#define BUFFER 256
void DelEnter(char *string){
if(string[strlen(string) -1] == '\n')
	string[strlen(string) - 1] = '\0';
}
int main(){
char nome[bUFFER];
fgets(nome, BUFFER, stdin);
DelEnter(nome);
printf("%zu caracteres!\n", strlen(nome));
}

Edited;

Testei agora sem o acento no 'e' e já deu 4... Porque é que os caracteres acentuados ocupam mais que 1 byte?

Edited by PsySc0rpi0n

Kurt Cobain - Grunge misses you

Nissan GT-R - beast killer

Share this post


Link to post
Share on other sites
thoga31

Testei agora sem o acento no 'e' e já deu 4... Porque é que os caracteres acentuados ocupam mais que 1 byte?

Além do link que o Happy te indicou, só vou adicionar uma nota: há vários modelos de representação de caracteres, e o mais comum é o ASCII, em que cada caracter ocupa 1 byte. Será saudável leres um pouco acerca do assunto. ;)


Knowledge is free!

Share this post


Link to post
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now

×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.