una tomografia tiempo tac studio radiacion puede programacion móviles libro hacer eliminar despues desarrollo curso cuanto como cada aplicaciones c string integer c99 scanf

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.