tomografia - manual de programacion android pdf
¿Cómo convertir una cadena en un tipo entero poco común? (3)
Algunos antecedentes: si quisiera usar, por ejemplo, scanf() para convertir una cadena en un tipo de entero estándar, como uint16_t , usaría SCNu16 desde <inttypes.h> , así:
#include <stdio.h>
#include <inttypes.h>
uint16_t x;
char *xs = "17";
sscanf(xs, "%" SCNu16, &x);
Pero un tipo entero más infrecuente como pid_t no tiene tal cosa; solo los tipos enteros normales son compatibles con <inttypes.h> . Para convertir de la otra manera, a portable printf() un pid_t , puedo convertirlo a intmax_t y usar PRIdMAX , así:
#include <stdio.h>
#include <inttypes.h>
#include <sys/types.h>
pid_t x = 17;
printf("%" PRIdMAX, (intmax_t)x);
Sin embargo, no parece haber una forma de escanear portátilmente scanf() en un pid_t . Entonces esta es mi pregunta: ¿cómo hacer esto de forma portátil?
#include <stdio.h>
#include <sys/types.h>
pid_t x;
char *xs = 17;
sscanf(xs, "%u", &x); /* Not portable! pid_t might not be int! /*
Pensé en scanf() a un intmax_t y luego comprobar que el valor está dentro de los límites de pid_t antes de pid_t a pid_t , pero no parece haber una manera de obtener los valores máximos o mínimos para pid_t .
Depende de qué tan portátil quieras ser. POSIX dice que pid_t es un tipo de entero con signo utilizado para almacenar ID de proceso e ID de grupo de proceso. En la práctica, se puede asumir con seguridad que el long es lo suficientemente grande. De lo intmax_t , su intmax_t debe ser lo suficientemente grande (por lo que aceptará cualquier pid_t válido); el problema es que ese tipo podría aceptar valores que no son legítimos en pid_t . Estás atrapado entre una roca y un lugar duro.
Usaría long y no me preocuparía mucho, excepto por un oscuro comentario en algún lugar que un arqueólogo de software de 100 años encontrará y observa, da una razón por la cual la CPU de 256 bits se detiene cuando se le entrega un valor de 512 bits como un pid_t .
POSIX 1003.1-2008 ya está disponible en la web (las 3872 páginas en PDF y HTML). Debes registrarte (gratis) Llegué a él desde la Librería Open Group .
Todo lo que veo allí es que debe ser un tipo entero con signo. Claramente, todos los valores enteros con signo válidos caben en intmax_t . No puedo encontrar ninguna información en <inttypes.h> o <unistd.h> que indique PID_T_MAX o PID_T_MIN u otros valores similares (pero esta noche solo he tenido acceso a él, por lo que podría estar oculto donde no lo he hecho). lo busqué). OTOH, estoy de acuerdo con mi comentario original: creo que los valores de 32 bits son pragmáticamente adecuados, y de todos modos usaría long , que sería de 64 bits en máquinas de 8 bits. Supongo que aproximadamente lo peor que podría pasar es que un proceso "apropiadamente privilegiado" lea un valor que sea demasiado grande y envíe una señal al proceso incorrecto debido a una falta de coincidencia de tipos. No estoy convencido de que estaría preocupado por eso.
... oooh! ... p400 en <sys/types.h>
La implementación debe admitir uno o más entornos de programación en los cuales los anchos de blksize_t, pid_t, size_t, ssize_t y suseconds_t no son mayores que el ancho de tipo long.
Existe una solución robusta y portátil, que es usar strtoimax() y verificar si hay desbordamientos.
Es decir, intmax_t un intmax_t , intmax_t si hay un error de strtoimax() , y luego también veo si "encaja" en un pid_t fundiéndolo y comparándolo con el valor intmax_t original.
#include <inttypes.h>
#include <stdio.h>
#include <iso646.h>
#include <sys/types.h>
char *xs = "17"; /* The string to convert */
intmax_t xmax;
char *tmp;
pid_t x; /* Target variable */
errno = 0;
xmax = strtoimax(xs, &tmp, 10);
if(errno != 0 or tmp == xs or *tmp != ''/0''
or xmax != (pid_t)xmax){
fprintf(stderr, "Bad PID!/n");
} else {
x = (pid_t)xmax;
...
}
No es posible utilizar scanf() , porque (como dije en un comentario) scanf() no detectará desbordamientos . Pero me equivoqué al decir que ninguna de las funciones relacionadas con strtoll() toma una intmax_t ; strtoimax() hace!
Tampoco funcionará usar nada más que strtoimax() menos que sepas el tamaño de tu tipo entero ( pid_t , en este caso).
Si está realmente preocupado, puede _assert(sizeof(pid_t) <= long) o el tipo que elija para su elemento ''%''.
Como se explica en esta respuesta , la especificación dice signed int . Si ''int'' cambia, su ''% u'' por definición cambia con él.