• Revista PROGRAMAR: Já está disponível a edição #53 da revista programar. Faz já o download aqui!

xerxes

Uma dor de cabeça para um novato.

32 mensagens neste tópico

Viva a toda a gente do forum, sou novato tanto aqui no forum como na programção, sei um pouco de c++ e por isso venho vos pedir ajuda com este meu programa. o programa é muito simples, mas eu tou a desatinar com isto.  Trata-se do seguinte, é um prog que le dia, mes, ano e hora, min e seg, e cria o seu timestamp, o meu problema é que quando tento a parti do timestamp voltar a hora k inseri, é.me retornado sempre datas e horas identicas mas sempre com alguns dias e horas a mais ou menos, n percebo o k está a passar. :hmm:  Valente abraço ao pessoal

Agradecia um pouquinho de atenção para este prob prog :wallbash: (lol)

O meu codigo fonte é este: :(

#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <dos.h>

int main(int argc, char *argv[])
{
time_t data;
struct tm dadosData;
unsigned int val1, val2, val3;

printf("Introduza a data nno seguinte formato (dd/mm/aaaa):");
scanf("%i%i%i", &val1, &val2, &val3);
	dadosData.tm_mday=val1;
	dadosData.tm_mon=val2;
	dadosData.tm_year=val3-1900;

printf("\n\nIntruduza a hora no seguinte formato(hh:mm:ss):");
scanf("%i%i%i", &val1, &val2, &val3);
	dadosData.tm_hour=val1;
	dadosData.tm_min=val2;
	dadosData.tm_sec=val3;

data=mktime(&dadosData);

printf("O timestamp dessa data e: %li\n", data);
printf ( "A data k inseris t getdate(: %s", asctime (&dadosData) );



getchar();



   getchar();
   return 0;
}

:wallbash:

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

%i não é nenhum tipo para usar com scanf....

Tens %d para números decimais inteiros, %u para positivos inteiros... %hd ou %hu para shorts, %ld ou %lu para longs..... etc.... %i não conheço...

EDIT:

Afinal %i existe, e eu não sabia, disse-me o triton, agora....

http://www.cppreference.com/stdio/printf.html

Vou voltar a olhar para o código.........

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

já que especificas assim:

dd/mm/aaaa

podes definir para ler assim:

scanf("%u/%u/%u", ...);

Uma vez que declaraste unsigned, lê unsigned, também....

//#include dos.h  // não serve para nada....

// ...
scanf("%u/%u/%u", &val1, &val2, &val3);
//...

//...
scanf("%i:%i:%i", &val1, &val2, &val3);
//...

Resultado

[ndray@nDesktop ~]$ ./a.out
Introduza a data nno seguinte formato (dd/mm/aaaa):20/02/1988


Intruduza a hora no seguinte formato(hh:mm:ss):06:45:27
O timestamp dessa data e: 574843527
A data k inseris t getdate(: Sun Mar 20 06:45:27 1988

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

N tou a conseguir, agora modifiquei o que m disses t e agora dá m erro do windows (enviar ou n enviar).

O fim deste programa é k ele peça a data e hora, faça o timestamp da mesma, e grave o timestamp num ficheiro de texto, depois mais tarde ele ira ler do ficheiro o timestamp para o poder converter de novo em data. Ahh outro prob, eu queria k aparecex a data final no formato dd/mm/aaaa, para poder ser comparda com outras datas.

Deste já agradeço a ajuda, é k estudar sozinho c++ n  é facil  :(

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Por que guardas o timestamp e não a string?

Eu acho que isso funciona, comigo funcionou, em linux.... Esse erro por vezes ocorre por causa de scanf's mal construidos....

Confere o teu código, deve haver aí um problema com casts ou assim...

BTW, o meu segundo scanf está mal... Era para ter %u:%u:%u.......................

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Pois, eu tou a programar no winXP,  :dontgetit: tou com o RELO da borland.

Conheçes algum compilador gratuito que me recomendes, é que já reparei que as vezes o meu compilador tem BUGS.

E nao queria gravar uma string pq depois o resto do meu programa fica a espera de um int para tratar... :-[

Abraço.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Eu uso GCC, mesmo em windows.... Instalas MinGW, e depois podes usar Code::Blocks para programar.... Eu uso gVim, que é só um editor de texto, mas não creio que te safes com ele, para já... Code::Blocks é muito bom, mesmo....

E agora reparo que o output do programa ficou mal.... 02 é suposto ser Fevereiro, mas no output está Março..... Isso é porque tm_mday vai de 0 a 11 e não de 1 a 12.... Seria esse o teu problema?

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Exacto, é mmo esse o prob k mencionei no meu primeiro topico... :biggrin:

Ele acrescenta ou diminui horas, dias ou meses.

E o RELO é so editor de de texto, se n tou em erro, é assim k programo. :ipool:

Continuo a precisar de ajuda!  :(:)

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Confere a documentação da struct tm e vê se estás a trabalhar como devias..... O caso dos meses é um que está mal, quem sabe os outros não estarão também...

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Sim eu sei. mas pareçe-me estar tudo ok com a estrutura. simplesment n consigo converter direito...

Tou farto de m derreter com isto :bored:

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Coloca aqui novamente o código que estás a utilizar e o output de um caso de erro.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

O código é exactamente o do meu primeiro post, uma vez k fiz as modificações k m disses t mas n consegui nada. N dá erro de compilação, mas cria o famoso erro de windows qd o scanf le para umas das variavais. (o erro de envio de reltoro para diagnostico da micrososft).

help, please.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Oh pah, isto para mim funciona... Não sei o que pode estar mal....

Com especial atenção que eu estou a compilar em C, e não em C++, mas isso não devia fazer diferença..... Tu próprio não usas bibliotecas de C++.....

#include <stdio.h>
#include <time.h>

int main()
{
    time_t timestamp;
    struct tm date;
    unsigned short int val1, val2, val3;

    printf("Insert date (dd/mm/yyyy): ");
    scanf("%hu%*[^0123456789]%hu%*[^0123456789]%hu", &val1, &val2, &val3);
    date.tm_mday = val1;
    date.tm_mon  = val2 - 1;
    date.tm_year = val3 - 1900;

    printf("Insert time (hh:mm:ss): ");
    scanf("%hu%*[^0123456789]%hu%*[^0123456789]%hu", &val1, &val2, &val3);
    date.tm_hour = val1;
    date.tm_min  = val2;
    date.tm_sec  = val3;

    printf("timestamp: %lu\n", mktime(&date));
    printf("ascii time: %s", asctime(&date));

    return 0;
}

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Olá!

O teu programa tinha alguns erros que convém esclarecer para não os cometeres mais (ou não tantas vezes  :P).

Para começar, não vejo onde é que este teu programa é especificamente escrito em C++, basicamente não usas nenhuma sintaxe de C++ mas antes de C. O que não tem mal, apenas não é um código-fonte exclusivamente de C++ (podes compilá-lo com um compilador de C ou de C++).

Depois acho que é preciso tomar cuidado com o uso de funções como o scanf que considero que é uma função bastante particular e delicada. Se não passares uma string com o formato correcto no scanf está tudo estragado e pode dar origem a sérios problemas na execução do teu programa.

Quando declaras variáveis deves inicializá-las a um valor por defeito, como para um int dar-lhe o valor 0 (por exemplo) e para uma estrutura como a tm deves colocar todos os seus membros a zero. Uma forma de fazer isto é com a função memset definida em strings.h. Isto impede que as tuas variáveis fiquem com valores que porventura já estejam em memória e assim sabes que as tuas variáveis não contêm valores incorrectos, aka lixo.

Por fim, e como bom programador que deves aspirar a ser (não resisti a dizer isto  :smoke:), deves ler documentação sobre as funções que vais usar para atingir os objectivos do teu programa. Quando recebes os dados para o valor do mês, tens que decrementar o valor do membro tm_mon pois este membro toma valores apenas no intervalo 0 a 11. Daí que possas estar a obter valores errados para o mês.

Vê esta página sobre esta mesma estrutura: http://www.cplusplus.com/reference/clibrary/ctime/tm.html

Segue abaixo o teu código que alterei e que funciona com o gcc 3.4.4 em ambiente Windows (Eclipse CDT + Cygwin).

Abraço! Qualquer dúvida que tenhas vai postando que prometo ajudar se arranjar tempo!

#include <stdio.h>
#include <time.h>
//para usar o memset
#include <strings.h>

int main(void)
{	
time_t data=0;	
struct tm * dadosData;	
int val1=0, val2=0, val3=0;
char valstr1=0, valstr2=0;

//inicializar os membros de dadosData a 0
memset(dadosData,0,sizeof(struct tm));

printf("Introduza a data no seguinte formato (dd/mm/aaaa):");
fflush(stdout);
scanf("%2d%1c%2d%1c%4d", &val1, &valstr1, &val2, &valstr2, &val3);
fflush(stdout);

//obter a informacao do tempo actual e modifica-la de acordo
//com o que o utilizador introduziu
time(&data);
dadosData = localtime(&data);

dadosData->tm_mday=val1;
//decrementar o mes
dadosData->tm_mon=val2-1;		
dadosData->tm_year=val3-1900;

printf("\n\nIntroduza a hora no seguinte formato(hh:mm:ss):");	
fflush(stdout);
scanf("%d:%d:%d", &val1, &val2, &val3);		
dadosData->tm_hour=val1;		
dadosData->tm_min=val2;		
dadosData->tm_sec=val3;

//ao chamar mktime vamos settar o membro dadosData->tm_wday
data=mktime(dadosData);

printf("O timestamp dessa data e: %ld\n", data);	
printf ( "A data que inseriste e' getdate: %s", asctime (dadosData) );

return 0;
}

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

2 problemas:

#include <strings.h>

O header que pretendes incluir é o string.h

	struct tm * dadosData;
//inicializar os membros de dadosData a 0
memset(dadosData,0,sizeof(struct tm));

Não podes inicializar nada porque só tens um apontador, não criaste a estrutura em memória. Admiro-me como não te deu erro ao tentares escrever em memória não alocada...

As inicializações são desnecessárias neste caso, e podem degradar a performance. Neste caso não, mas se fosse numa função que fosse chamada repetidamente, colocar os valores a 0 ou não pode fazer uma grande diferença.

Aqui:

	scanf("%2d%1c%2d%1c%4d", &val1, &valstr1, &val2, &valstr2, &val3);

também não faz sentido ler os caracteres separadores da data para variáveis; só serve para perder mais tempo... Aliás, no caso das horas procedeste bem:

scanf("%d:%d:%d", &val1, &val2, &val3);

Não faz sentido utilizar uma linguagem cuja principal vantagem é a performance se esta não é aproveitada. De outro modo mais valia utilizar Java, ou C#, ou Python ou algo assim, em que provavelmente é muito mais fácil escrever um programa deste género.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

2 problemas:

#include <strings.h>

O header que pretendes incluir é o string.h

Tens razão, é o string.h e não o strings.h.

	struct tm * dadosData;
//inicializar os membros de dadosData a 0
memset(dadosData,0,sizeof(struct tm));

Não podes inicializar nada porque só tens um apontador, não criaste a estrutura em memória. Admiro-me como não te deu erro ao tentares escrever em memória não alocada...

SIm, o que eu queria ter feito era criar a variável dadosData como estrutura e não como apontador. Aí sim deveria ter settado os membros a zero.

As inicializações são desnecessárias neste caso, e podem degradar a performance. Neste caso não, mas se fosse numa função que fosse chamada repetidamente, colocar os valores a 0 ou não pode fazer uma grande diferença.

Como esta função não é chamada em ciclo não há problema nenhum em colocar valores a 0, não se introduz nenhum bug ao fazer isso e acho que é uma prática recomendável.

Aqui:

	scanf("%2d%1c%2d%1c%4d", &val1, &valstr1, &val2, &valstr2, &val3);

também não faz sentido ler os caracteres separadores da data para variáveis; só serve para perder mais tempo... Aliás, no caso das horas procedeste bem:

scanf("%d:%d:%d", &val1, &val2, &val3);

É uma das maneiras possíveis de resolver o problema. É certo que não é preciso ler os caracteres separadores mas também não há problema em o fazer...

Não faz sentido utilizar uma linguagem cuja principal vantagem é a performance se esta não é aproveitada. De outro modo mais valia utilizar Java, ou C#, ou Python ou algo assim, em que provavelmente é muito mais fácil escrever um programa deste género.

Não me parece que a performance seja sequer considerada aqui para um problema tão simples como este. Só quis fazer código que realmente funcionasse sem me preocupar com a performance e no pouco tempo que estive a ver este post. A ideia era ajudar o xerxes a perceber o código e o que estava mal, e não a fazer o código com a melhor performance.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

As inicializações a zero são indiferentes, se logo a seguir vais definir os valores... talvez na struct faça algum sentido porque não vamos definir todos mas, de resto, não é isso que altera a segurança do programa....

Ler caracteres para varíaveis só porque não os vais usar, isso é falta de conhecimento das potencialidades do scanf.... fazes %*c e pronto, está descartado, não precisas de alocar......

Definir valores para zero em ciclos não dá problema, antes pelo contrário... Não o fazer, quando se deveria, é que dá..... Nesse caso é que não há problema....

Uma coisa é menosprezar a performance para resolver um problema de forma mais simples, outra é desprezá-la para fazer código desnecessário.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Ler caracteres para varíaveis só porque não os vais usar, isso é falta de conhecimento das potencialidades do scanf.... fazes %*c e pronto, está descartado, não precisas de alocar......

Eu sei disso, simplesmente postei uma possível solução que na altura não tive tempo para melhorar.

Uma coisa é menosprezar a performance para resolver um problema de forma mais simples, outra é desprezá-la para fazer código desnecessário.

Mais uma vez digo que a questão que aqui se coloca não é a de obter a melhor performance. Fiz rapidamente um código que funcionava. Ponto. Não tive tempo de olhar melhor para o código que fiz, só isso. Se tivesse mais tempo era outro o código que fazia. Mas sinceramente achas que é por fazer um %c em vez de um %*c que vais perder assim tanta performance num problema deste?

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Eu não fazia aquilo de forma imediata.... A forma mais imediata era mesmo nem ler.... Mas pronto, cada um processa os problemas a seu gosto....

Não estou a falar de performance, estou a falar de práticas...

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Mas sinceramente achas que é por fazer um %c em vez de um %*c que vais perder assim tanta performance num problema deste?

Como eu disse, o problema não é este caso, mas sim outros em que a performance conte. Os piores hábitos ganham-se ao início.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Ok, n sei como fazer.

Vcs falam em GCC eu n sei o k é isso.

Só sei k no RELO qd compilo o prog k m dest, n consigo abrir a library sys/cdefs.h da strings.h.

nunca usei outro prog para programar sem ser o RELO, como faço para ter um de jeito?

Abraço

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Pah, já que estás a programar em C e não em C++, experimenta LCC-Win32... És capaz de ter de pesquisar por links de download, mas é simples e funciona muito bem....

Quando já estiveres desenrascado, instala MinGW (vai à secção de downloads, Sourceforge, e saca o MinGW-5.1.3 Automated Installer). Corres isso, escolhes, pelo menos, GCC e G++ para C e C++, respectivamente. Aconselho a escolha dos pacotes "candidate", e que instales na directoria predefinida.

Depois convém adicionares os binários às variáveis de ambiente, para poderes usar os programas como em linux. Executas, na consola, este comando: "set path=%path%;C:\MinGW\bin", assumindo que foi essa a pasta onde instalaste...

Depois disso sacas uma nightly build do Code::Blocks, lê bem de que ficheiros precisas de sacar mais, está tudo documentado.

Quando correres o Code::Blocks pela primeira vez, escolhes o MinGW GCC como compilador, e pronto, está feito...

Estes programas encontram-se bem no google pesquisando simplesmente pelo seu nome...

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

ok, pessoal, agora tou a usar o dev-C++, ja consigo compilar o codigo, ja consigo k seja criado o ficheiro executavel, o problema agora é k quando executo o programa, n chega a fazer nada pq dá o famosos erro do windows de enviar ou n enviar, ja tentei noutros pcs e o problema mantem-se.

Deste já um imenso obrigado a todos k m ajudam.

Este é o  codigo k  estou a usar:

#include <stdio.h>
#include <time.h>//para usar o memset
#include <string.h>

int main(void)
{
time_t data=0;
struct tm * dadosData;		
int val1=0, val2=0, val3=0;	
char valstr1=0, valstr2=0;

//inicializar os membros de dadosData a 0	
memset(dadosData,0,sizeof(struct tm));

printf("Introduza a data no seguinte formato (dd/mm/aaaa):");
fflush(stdout);	
scanf("%2d%1c%2d%1c%4d", &val1, &valstr1, &val2, &valstr2, &val3);	
fflush(stdout);

//obter a informacao do tempo actual e modifica-la de acordo
//com o que o utilizador introduziu	
time(&data);	
dadosData = localtime(&data);

dadosData->tm_mday=val1;
//decrementar o mes	
dadosData->tm_mon=val2-1;			
dadosData->tm_year=val3-1900;

printf("\n\nIntroduza a hora no seguinte formato(hh:mm:ss):");		
fflush(stdout);	
scanf("%d:%d:%d", &val1, &val2, &val3);			
dadosData->tm_hour=val1;			
dadosData->tm_min=val2;			
dadosData->tm_sec=val3;	

//ao chamar mktime vamos settar o membro dadosData->tm_wday	
data=mktime(dadosData);

printf("O timestamp dessa data e: %ld\n", data);		
printf ( "A data que inseriste e' getdate: %s", asctime (dadosData) );	

return 0;	
}

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Esse problema dá quando tentas executar o binário dentro do Dev-C++? Ou tentas correr o programa a partir da pasta onde está o binário com um duplo-clique em cima do binário? Strange...  :D

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!


Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.


Entrar Agora