thinkabout Posted July 13, 2013 at 07:04 PM Report #518656 Posted July 13, 2013 at 07:04 PM 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); } } } }
Rui Carlos Posted July 14, 2013 at 07:09 PM Report #518735 Posted July 14, 2013 at 07:09 PM 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 } } } } } Rui Carlos Gonçalves
thinkabout Posted August 25, 2013 at 04:04 PM Author Report #522608 Posted August 25, 2013 at 04:04 PM (edited) 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 August 25, 2013 at 04:05 PM by thinkabout
Rui Carlos Posted August 25, 2013 at 04:47 PM Report #522611 Posted August 25, 2013 at 04:47 PM fulanoX devia ser uma variável do tipo char*. Rui Carlos Gonçalves
thinkabout Posted August 25, 2013 at 06:56 PM Author Report #522616 Posted August 25, 2013 at 06:56 PM (edited) 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 August 25, 2013 at 06:59 PM by thinkabout
Rui Carlos Posted August 25, 2013 at 07:11 PM Report #522617 Posted August 25, 2013 at 07:11 PM 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. Rui Carlos Gonçalves
thinkabout Posted August 25, 2013 at 07:40 PM Author Report #522621 Posted August 25, 2013 at 07:40 PM (edited) 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 August 25, 2013 at 07:50 PM by thinkabout
HappyHippyHippo Posted August 25, 2013 at 07:55 PM Report #522622 Posted August 25, 2013 at 07:55 PM 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 Portugol Plus
thinkabout Posted August 25, 2013 at 08:06 PM Author Report #522626 Posted August 25, 2013 at 08:06 PM Tinha lá chegado mesmo agora. http://stackoverflow.com/questions/2404794/strcmp-on-a-line-read-with-fgets int main() { contactos lista[MAX]; char fulanoX[10]; int i, total=0; fgets(fulanoX, 9, stdin); fulanoX[strlen(fulanoX) - 1] = '\0'; printf("o fulano e o %s \n", fulanoX); Obrigado de qualquer forma.
PsySc0rpi0n Posted August 25, 2013 at 10:00 PM Report #522638 Posted August 25, 2013 at 10:00 PM 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
HappyHippyHippo Posted August 25, 2013 at 10:15 PM Report #522642 Posted August 25, 2013 at 10:15 PM 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 Portugol Plus
PsySc0rpi0n Posted September 3, 2013 at 11:26 AM Report #523279 Posted September 3, 2013 at 11:26 AM (edited) 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 September 3, 2013 at 11:27 AM by PsySc0rpi0n Kurt Cobain - Grunge misses you Nissan GT-R - beast killer
HappyHippyHippo Posted September 3, 2013 at 11:40 AM Report #523282 Posted September 3, 2013 at 11:40 AM Testei agora sem o acento no 'e' e já deu 4... Porque é que os caracteres acentuados ocupam mais que 1 byte? http://en.wikipedia.org/wiki/UTF-8 IRC : sim, é algo que ainda existe >> #p@p Portugol Plus
thoga31 Posted September 3, 2013 at 08:03 PM Report #523374 Posted September 3, 2013 at 08:03 PM 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!
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now