Autor
|
Tema: Pasar string a time. Número de días entre dos fechas (Leído 4,162 veces)
|
capitandelpanel
Desconectado
Mensajes: 1
|
Buenas!
Necesito un programa que me calcule el número de días que faltan desde una fecha (que introduce el usuario por teclado) a la fecha actual. Por ahora lo que llevo echo es que me diga el día del año en el que estamos:
int main() { time_t tiempo,puntero; char ,diaano[80], int aux; struct tm *tmPtr;
tiempo = time(NULL); tmPtr = localtime(&tiempo);
strftime( diaano, 80, "%j", tmPtr);
printf("El dia del año es: %s\n", diaano );
aux = atoi( diaano );
return 0; }
Ahora necesito hacer el mismo proceso con la fecha que introduce el usuario y luego restar estos dos números. Lo que no doy conseguido es pasar un string(la fecha que introduce el usuario) a un dato tipo time.
Asi mismo el programa también me tiene que saltar un aviso si la fecha que introducimos es anterior a la fecha actual.
¿alguna solución?
gracias
|
|
|
En línea
|
|
|
|
rir3760
Desconectado
Mensajes: 1.639
|
Para obtener la diferencia (en segundos) de dos fechas puedes utilizar la función difftime, esta requiere dos argumentos de tipo time_t, el primero es la fecha actual y la obtienes mediante una llamada a la función time. La segunda fecha la introduce el usuario, aquí puedes obtener directamente los valores de dia, mes y año para una estructura tipo "struct tm" y a partir de esta obtener uno de tipo time_t con mktime. Mas o menos así: struct tm d = {0}; time_t b; puts("Introduce la fecha (aaaa mm dd):"); if (scanf("%d %d %d", &d. tm_year, &d. tm_mon, &d. tm_mday) != 3) return EXIT_FAILURE; d.tm_year -= 1900; /* 0 == 1900, 100 == 2000, etc. */ d.tm_mon--; /* 0 == Enero, 1 == Febrero, etc. */ /* Validacion de los campos tm_year, tm_mon y tm_mday */ /* ... */
Un saludo
|
|
|
En línea
|
C retains the basic philosophy that programmers know what they are doing; it only requires that they state their intentions explicitly. -- Kernighan & Ritchie, The C programming language
|
|
|
Peregring-lk
Desconectado
Mensajes: 50
|
#include "stdio.h" #include "time.h" #define SEGS_DIA 86400 int main() { struct tm fecha = {}; // Inicializamos la estructura a 0. // Asumimos que el formato de fecha introducido por el usuario es correcto. printf("Introduce la fecha: "); scanf("%u%u%u", &fecha. tm_mday, &fecha. tm_mon, &fecha. tm_year); --fecha.tm_mon; // La estructura tm numera los meses del 0 al 11. fecha.tm_year -= 1900; // Los annos comienzan en 1900. // No utilizo difftime porque devuelve un `double` y me da coraje. int diff = (mktime(&fecha ) - time(NULL )) / SEGS_DIA ; printf("\nLa diferencia es: %d\n", diff ); return 1; }
Si quisiéramos comprobar el formato de entrada mejor, el `scanf` sería algo más "complejo": char truco; int leidos = scanf("%2u%2u%4u%c", &fecha. tm_mday, &fecha. tm_mon, &fecha. tm_year, &truco ); if (leidos != 3) if (tm_year < 1000) // Asumimos que el anno debe tener al menos 4 digitos.
Los numeritos (el 2 o el 4) son para indicar el "ancho" máximo que tendrá cada campo. El otro "truco" (la `%c` final) sirve para evitar que el usuario introduzca cadenas más largas de la cuenta; por ejemplo: "24 11 19900asd". El formato de entrada sería correcto para `scanf`, porque los cuatro primeros dígitos del campo "año" se guardan correctamente. El problema es que `scanf` deja de "leer" e ignora el resto de la cadena, así que lo forzamos a leer al menos uno más, y si ha recuperado 4, es que la cadena era demasiado larga.
|
|
« Última modificación: 17 Mayo 2015, 20:22 pm por Peregring-lk »
|
En línea
|
|
|
|
rir3760
Desconectado
Mensajes: 1.639
|
El otro "truco" (la `%c` final) sirve para evitar que el usuario introduzca cadenas más largas de la cuenta; por ejemplo: "24 11 19900asd". El especificador "%c" al igual que "%[]" no descartan el espacio blanco inicial, por ello una linea que consista de los tres numeros (validos) para la fecha seguida del avance de linea (lo usual) resultara en la función scanf retornando cuatro. La aproximación mas sencilla (en este caso) es utilizar scanf para leer y validar los tres números, a continuación se utiliza un bucle con getchar para verificar que el resto solo sea espacio/tabulador/etc. seguidos del carácter '\n'. O bien se puede utilizar solo scanf pero queda (en mi opinión) muy feo: int leidos = scanf("%2u%2u%4u", &fecha. tm_mday, &fecha. tm_mon, &fecha. tm_year) == 3 && (scanf("%*[ \t]"), scanf("%1[\n]", &truco ) == 1) ;
Un saludo
|
|
|
En línea
|
C retains the basic philosophy that programmers know what they are doing; it only requires that they state their intentions explicitly. -- Kernighan & Ritchie, The C programming language
|
|
|
Peregring-lk
Desconectado
Mensajes: 50
|
Tienes razón en lo del carácter fin de línea. Mi solución es, quizás, más adecuada para cadenas recibidas como parámetro (`sscanf`), que para comprobar directamente la entrada. De todas formas, ¿no es ésta una solución más sencilla? /* Con barras invertidas para que tenga más "pinta" de fecha :) leidos = scanf("%2u/%2u/%4u%c", &dia, &mes, &anno, &truco); if (leidos < 3) exit(EXIT_FAILURE); if (leidos > 3 && truco != '\n')) exit(EXIT_FAILURE);
De ésta forma, solo permitimos una fecha seguida inmediatamente por un salto de línea. No creo que haga falta comprobar todo lo que venga detrás, sencillamente, con obligar al usuario a escribir la fecha y luego justo después, pulsar "Intro", sería suficiente.
|
|
|
En línea
|
|
|
|
rir3760
Desconectado
Mensajes: 1.639
|
¿no es ésta una solución más sencilla? En el caso que mencionas si, es mas corta. Por cierto se puede abreviar un poco mas. Cuando la fecha para ser valida solo puede ser seguida del avance de linea puedes indicarlo en la cadena de formato con "%1[\n]" y verificar que el resultado de la función sea igual a cuatro. Mas o menos así: if (scanf("%2u/%2u/%4u%1[\n]", &dia , &mes , &anno , &truco ) == 4){ }else { puts("Entrada no valida"); }
Edito: Ups, el especificador "%[]" almacena los caracteres coincidentes seguidos de un '\0' por lo que el objeto destino no puede ser una variable de tipo char sino un array de estos (mea culpa). Un saludo
|
|
« Última modificación: 3 Junio 2015, 16:33 pm por rir3760 »
|
En línea
|
C retains the basic philosophy that programmers know what they are doing; it only requires that they state their intentions explicitly. -- Kernighan & Ritchie, The C programming language
|
|
|
|
Mensajes similares |
|
Asunto |
Iniciado por |
Respuestas |
Vistas |
Último mensaje |
|
|
Calcular días entre dos fechas...
Ejercicios
|
*-.Sub-Vorbio.-*
|
0
|
5,006
|
13 Noviembre 2008, 00:51 am
por *-.Sub-Vorbio.-*
|
|
|
Calcular numero de días entre dos fechas!
Java
|
*-.Sub-Vorbio.-*
|
9
|
40,076
|
26 Marzo 2009, 23:34 pm
por Choclito
|
|
|
intervalo entre fechas
Programación Visual Basic
|
z_ane_666
|
4
|
2,714
|
8 Noviembre 2011, 13:34 pm
por 79137913
|
|
|
Programa que calcule la diferencia de días entre dos fechas
Programación C/C++
|
davisinful
|
2
|
13,076
|
10 Noviembre 2011, 00:57 am
por rir3760
|
|
|
Numero de dias que separan ambas fechas.
Programación C/C++
|
mario.ar
|
1
|
2,268
|
8 Febrero 2013, 15:48 pm
por engel lex
|
|