2010-11-13 12 views
5

Este código me da advertencias:Cómo leer datos en una variable time_t usando scanf()?

$ cat test.c 
#include<stdio.h> 
#include<time.h> 

int main() { 

    time_t t; 
    scanf("%lld", &t); 
    printf("%lld\n", t); 
    return 0; 
} 
$ gcc test.c -o test 
test.c: In function ‘main’: 
test.c:7: warning: format ‘%lld’ expects type ‘long long int *’, but argument 2 has type ‘time_t *’ 
test.c:8: warning: format ‘%lld’ expects type ‘long long int’, but argument 2 has type ‘time_t’ 
$ 

Aparte de las advertencias, el código funciona como se esperaba.

¿Qué debo hacer para no recibir las advertencias en la compilación (no compila los trucos de pragma, por favor)?

Respuesta

8

El tipo exacto de time_t depende de su plataforma y sistema operativo. Todavía es bastante a menudo de 32 bits (ya sea int o long), no 64, y algunos incluso usan flotadores. Lo correcto es leer en un entero de tamaño conocido (int o long long) y luego asignar el valor a time_t como segundo paso.

+0

Usaría el tamaño más grande posible para estar seguro. Y 'strtoull' sería una mejor opción que' scanf'. –

+0

@R ..: 'strtoll()' ya que 'time_t' generalmente está firmado. –

+0

+1. De hecho, POSIX permite que 'time_t' sea un tipo flotante real o entero. – dreamlax

3

Necesita el formato para que coincida con la definición time_t de su sistema. Compilar con

gcc test.c -o test --save-temps 

continuación

grep time_t test.i|grep typedef 

Probablemente, esto le dirá que time_t es "long int", por lo que necesita para escanear con "% ld".

+0

Y si obtiene diferentes respuestas en diferentes arquitecturas, puede 'ifdef' su código para que sea 'portátil' para ellos – rano

2

En primer lugar, su compilador tiene razón: nada garantiza que time_t sea realmente un entero de 64 bits con signo. Podría ser un entero de 32 bits o incluso un valor de coma flotante, según la plataforma.

Ahora, si estás absolutamente , positivamente seguro de que es un time_tlong long en su plataforma, y ​​se quiere evitar las advertencias de formato, que puede hacer:

time_t t; 
scanf("%lld", (long long *) &t); 
printf("%lld\n", (long long) t); 
1

Utilice un tamaño conocido del número entero con scanf() y luego convertir el resultado a time_t:

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

int main() 
{ 
    long long llv; 
    time_t t; 
    scanf("%lld", &llv); 
    t = llv; 
    printf("%lld\n", (long long)t); 
    return 0; 
} 

En este ejemplo, no parece que comprar mucho, pero si usted quiere pasar la variable t a algunas de las funciones de manipulación del tiempo, entonces tendría el tipo correcto para trabajar.

Si mira la URL enlazada para (la versión extendida de POSIX) scanf(), verá que no hay mención de time_t escriba allí. Por lo tanto, cualquier mecanismo para leer time_t valores con scanf() tiene que ser algo menos que directo. Ídem, cualquier cosa que imprima time_t valores también es algo menos que directa.