Listar chamadas não atendidas de um telemovel.

PHP, Java, JavaScript, XML, XHTML, HTML, CSS, ASP, Delphi, Assembly, LaTeX, C, UML, Flash, Perl, SQL, Python, Zope, Pascal, WML. Se conhece mais de 3 siglas referidas, este é o forum para si.

Moderadores: Administradores, Moderadores

Listar chamadas não atendidas de um telemovel.

Mensagempor SpecialOne » Segunda Mai 11, 2009 10:12

A ideia é fazer um programa que liste as chamadas não atendidas de um telemovel, usando listas ligadas.

O programa esta com alguns bugs, nomeadamente, não imprime a data e, eu insiro dois numero na lista e quando tento imprimir o conteudo da lista so imprime o ultimo ultimo inserido.

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

/* Estrutura da lista */

typedef struct ListNA{
int num;
char data[9]; /* Formato da data di-me-an do tipo 21-12-09 */
char hm[5]; /* formato da hora ho:mi do tipo 21:34 */
struct ListNA *seg;
} Chamadas;

typedef Chamadas *NaoAtendi;

/* Função que verifica se uma lista esta vazia */

int vazia(NaoAtendi l){
return l == NULL;
}

/* Função que cria uma lista vazia */

NaoAtendi criaLista(){
return NULL;
}

/* Função que insere na cabeça da lista a informação relativa a chamadas não atendidas */

NaoAtendi insereCab(int n,char *d, char *h,NaoAtendi l){
NaoAtendi aux;
aux = (NaoAtendi) malloc(sizeof(Chamadas));

if(vazia(l)) { aux -> num = n; /* Se a lista l (fornecida como parametro estiver vazia */
strcpy(aux->data,d); /* Copia para a lista aux campo data a data que é fornecida como parametro */
strcpy(aux->hm,h); /* Copia para a lista aux campo hora a hora que é fornecida como parametro */
aux -> seg = NULL;
l = aux;
return l;
}
else { aux -> num = n; /* Se a lista l (fornecida como parametro estiver vazia */
strcpy(aux->data,d); /* Copia para a lista aux campo data a data que é fornecida como parametro */
strcpy(aux->hm,h); /* Copia para a lista aux campo hora a hora que é fornecida como parametro */
aux -> seg = l;
return aux;
}
}

/* Função que imprime chamadas*/

void imprimeCha(NaoAtendi l) {
NaoAtendi r;
for(r=l;!vazia(r);r=r->seg){
printf("Numero: %d \n data: %s \n hora: %s \n",r->num,r->data,r->hm);
}
free(r);

}

int main(){

int n,i,k;
char dat[9];
char hora[5];
NaoAtendi l;
l = criaLista();

printf("Quantos numeros quer inserir ?\n");
scanf("%d",&k);

for(i=0;i<k;i++){

printf("Insira o numero de telemovel\n");
scanf("%d",&n);

printf("Insira a data com o seguinte formato di-me-an, do tipo 12-01-09\n");
scanf("%s",dat);

printf("Valor da variavel data %s\n",dat);

printf("Insira a hora com o seguinte formato ho:mi, do tipo 12:23\n");
scanf("%s",hora);
}

l = insereCab(n,dat,hora,l);

imprimeCha(l);

return 0;

}
SpecialOne
Novato
Novato
 
Mensagens: 7
Registado: Terça Nov 04, 2008 14:08

Mensagempor SpecialOne » Segunda Mai 11, 2009 10:26

Em relação `a função que imprime lista ja esta resolvido.

Eu tinha

/* Função que imprime chamadas*/

void imprimeCha(NaoAtendi l) {
NaoAtendi r;
for(r=l;!vazia(r);r=r->seg){ Aqui tinha r = l->seg em vez de ter r = r -> seg;
printf("Numero: %d \n data: %s \n hora: %s \n",r->num,r->data,r->hm);
}
free(r);

}

Ja corrigi esse bug no post inicial.

Agora não sei porque é que não imprime a data.

Alguem tem alguma ideia de como posso testar se a hora é inserida é valida e o mesmo para a data.
SpecialOne
Novato
Novato
 
Mensagens: 7
Registado: Terça Nov 04, 2008 14:08

Mensagempor vamosAeles » Segunda Mai 11, 2009 11:10

Boas,

penso que o array da hora não tem o tamanho suficiente, e como tás em C, ele não se queixa.

Também tens de contar com o '\0' quando declaras um array, para conter uma string.

Quando fazes o scanf penso que ele coloca o '\0' no fim, ie, já fora do array. Em C ele não se queixa, mas se endereço onde fica o '\0' é de uma outra variável, e esta deixa de conter o '\0', quando fazes printf desse array, ele começa a imprimir sequencialmente todas as posições até encontrar um '\0' ... ou rebentar.

Experimenta por char[6] para o array da hora.
vamosAeles
Membro de Prata
Membro de Prata
 
Mensagens: 206
Registado: Quarta Jan 04, 2006 21:29
Localização: Lisboa/Proença

Mensagempor SpecialOne » Segunda Mai 11, 2009 18:59

A hora esta a imprimir bem.

A data é que não.

O formato da data é do tipo: 11-05-09 , o meu array tem 9 posições
SpecialOne
Novato
Novato
 
Mensagens: 7
Registado: Terça Nov 04, 2008 14:08

Mensagempor vamosAeles » Segunda Mai 11, 2009 21:31

Boas,

mas mesmo a colocares char[6] na hora, a data continua a não ser impressa?

PS: em relação a só imprimir o último, coloca "l = insereCab(n,dat,hora,l); " como última instrução do fim do ciclo, e não fora
vamosAeles
Membro de Prata
Membro de Prata
 
Mensagens: 206
Registado: Quarta Jan 04, 2006 21:29
Localização: Lisboa/Proença

Mensagempor SpecialOne » Segunda Mai 11, 2009 22:34

char[6] na hora ja imprime a data.

Agradeço a ajuda.

Tenho agora mais uma duvida, como é que posso verificar se a hora a data são validas.

hora valida = hora entre 0 e 23 e minutos entre 0 e 59.

data valida = dia entre 1 e 31, mes entre 1 e 12 e ano entre 00 e 99.
SpecialOne
Novato
Novato
 
Mensagens: 7
Registado: Terça Nov 04, 2008 14:08

Mensagempor vamosAeles » Terça Mai 12, 2009 9:04

Nunca fiz parse de datas e horas em C.

Vê se estas funções chegam para o que precisas:
http://www.elook.org/programming/c/stddate.html

Cumps,
[[]]
vamosAeles
Membro de Prata
Membro de Prata
 
Mensagens: 206
Registado: Quarta Jan 04, 2006 21:29
Localização: Lisboa/Proença

Mensagempor wykzl » Terça Mai 12, 2009 15:48

SpecialOne Escreveu:char[6] na hora ja imprime a data.

Há muito, muito tempo que não programo em C, mas há erros que persistem.
O pior é que há muitos programadores que "resolvem" a situação com "dá-se mais um espaço no array e já deve funcionar" sem perceber o porquê (são coisas do C...maldita linguagem...)

O vamosAeles foi certeiro na questão do scanf.
Na data estava bem porque tinhas o espaço extra.

Para além da sintaxe é importante "pensar C"...ou seja, pensar como é que as coisas são feitas pelo compliador e isso muitas vezes não é ensinado...

Depois há projectos que andam semanas em debug ou então têm TODOS os arrays do estilo:
char data[255];
char hora[255];
:roll:
wykzl
Aprendiz
Aprendiz
 
Mensagens: 41
Registado: Domingo Abr 19, 2009 18:27

Mensagempor vamosAeles » Terça Mai 12, 2009 16:51

Tens toda a razão, o C tens destas coisas.

Pegando no exemplo da thread, se à volta de cada declaração dos arrays no main e na estrutura, se se colocassem la umas variaveis qq q nunca fossem usadas, mesmo com char[5] mt provalvelmente o programa iria funcionar as mil maravilhas, mas lá está, o erro de programação de fundo continuava lá.

Cumps,
[[]]
vamosAeles
Membro de Prata
Membro de Prata
 
Mensagens: 206
Registado: Quarta Jan 04, 2006 21:29
Localização: Lisboa/Proença

Mensagempor SpecialOne » Terça Mai 12, 2009 21:09

Uma outra duvida que tenho é, quando executo o programa e insiro o numero, data e hora, ao fim da inserção eles são impressos, mas se voltar a executar e inserir novos dados os que inseri na primeira execução ja não estão la, como resolvo isso?

Eu sei que na função main eu declaro l como apontador para a estrutura (NaoAtendi l; ) e depois faço l = criaLista(); para inicializar a lista l (fica l = NULL), penso que o problema estara nesta zona.
SpecialOne
Novato
Novato
 
Mensagens: 7
Registado: Terça Nov 04, 2008 14:08

Mensagempor vamosAeles » Terça Mai 12, 2009 21:53

Boas,

que queres dizer com voltar a executar? Executar de novo o programa?
Se for o caso... só guardando num ficheiro ou BD, pois quando o programa acaba tudo o que está em memória vai à vida!!...

[[]]
vamosAeles
Membro de Prata
Membro de Prata
 
Mensagens: 206
Registado: Quarta Jan 04, 2006 21:29
Localização: Lisboa/Proença

Mensagempor SpecialOne » Quarta Mai 13, 2009 23:10

É executar de novo programa.

Vou ter que dar uma vista de olhos na materia sobre ficheiros.
SpecialOne
Novato
Novato
 
Mensagens: 7
Registado: Terça Nov 04, 2008 14:08

Mensagempor wykzl » Quinta Mai 14, 2009 16:04

SpecialOne Escreveu:char[6] na hora ja imprime a data.

Agradeço a ajuda.

Tenho agora mais uma duvida, como é que posso verificar se a hora a data são validas.

hora valida = hora entre 0 e 23 e minutos entre 0 e 59.

data valida = dia entre 1 e 31, mes entre 1 e 12 e ano entre 00 e 99.

Se não for para tu usares com os devidos cuidados, então tens de alterar o código de forma a prevenires que, apesar dos avisos, não te introduzam datas do estilo 2009/05/14 ou 15-05-2009... mais que 9 caracteres...overflow...pufff

Não esquecer que o utilizador é o teu maior adversário...ele consegue-se lembrar de fazer coisas que não te passa pela cabeça :P

A minha sugestão é teres o scanf para uma string maiorzinha, a qual passas à função de validação e cujo retorno é guardado no string da data (o mesmo com a hora).

Aliás...scanf é porreiro para introduzir dados, mas é uma fonte de bugs porque o utilizador pode-te avacalhar o sistema todo (pedes NN:NN e ele escreve o nome...agora faz lá parse disso...). Se for para usar em ambiente "não controlado", então tens de escrever uma função para ler aquilo que queres, estilo data=InputData(); hora=InputHora();
wykzl
Aprendiz
Aprendiz
 
Mensagens: 41
Registado: Domingo Abr 19, 2009 18:27

Mensagempor wykzl » Quinta Mai 14, 2009 16:19

É bem verdade que faz muito tempo que não mexo em C.
Mas...

void imprimeCha(NaoAtendi l)
{
NaoAtendi r;

for(r=l;!vazia(r);r=r->seg)
{
printf("Numero: %d \n data: %s \n hora: %s \n",r->num,r->data,r->hm);
}
free(r);
}

Não tens aqui um bug ?

R começa com o primeiro elemento da lista e percorre toda a lista até que está vazio (r = NULL).
Depois fazes ... free (NULL)
Não libertaste qualquer espaço da lista e tentas libertar NULL (geralmente isso dá em nada, mas com um compilador mais manhoso dá raia...por exemplo, acho que em C++ tinhas aí um estouro).

Já agora uma alternativa

for(NaoAtendi r=l;!vazia(r);r=r->seg)
printf("Numero: %d \n data: %s \n hora: %s \n",r->num,r->data,r->hm);
Desta forma o free não funciona (se bem me lembro, o compilador dá erro de variável não definida) e apanhas logo a manobra do free(null);
wykzl
Aprendiz
Aprendiz
 
Mensagens: 41
Registado: Domingo Abr 19, 2009 18:27

Mensagempor SpecialOne » Sexta Mai 15, 2009 18:09

Tens razão.

O free(r) ficou por engano, eu não estou a alocar memoria para r por isso não preciso de a libertar, foi um bug.
SpecialOne
Novato
Novato
 
Mensagens: 7
Registado: Terça Nov 04, 2008 14:08


Voltar para Programação

Quem está ligado:

Utilizador a ver este Fórum: Nenhum utilizador registado e 1 visitante

cron