Frage

Einige Hintergrundinformationen: Wenn ich zum Beispiel verwenden wollte, scanf() einen String in einem Standard-Integer-Typ zu konvertieren, wie uint16_t, ich SCNu16 von <inttypes.h> verwenden würde, wie folgt aus:

#include <stdio.h>
#include <inttypes.h>
uint16_t x;
char *xs = "17";
sscanf(xs, "%" SCNu16, &x);

Aber ein seltener Integer-Typ wie pid_t hat keine solche Sache; nur die normalen Integer-Typen werden durch <inttypes.h> unterstützt. Um die andere Art und Weise zu konvertieren, zu portably eine printf() pid_t, ich kann es zu gieße intmax_t und verwenden PRIdMAX, wie folgt aus:

#include <stdio.h>
#include <inttypes.h>
#include <sys/types.h>
pid_t x = 17;
printf("%" PRIdMAX, (intmax_t)x);

Doch es scheint keinen Weg, um portabel in eine scanf() pid_t. Das ist also meine Frage: Wie diese portably tun

#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! /*

Ich dachte an scanf()ing zu einem intmax_t und dann prüfen, ob der Wert innerhalb pid_t der Grenzen vor dem pid_t Gießen, aber es scheint nicht ein Weg zu sein, um die Maximal- oder Minimalwerte für pid_t zu erhalten.

War es hilfreich?

Lösung

Es ist eine robuste und tragbare Lösung, die strtoimax() zu verwenden ist und prüfen, ob überläuft.

Das heißt, ich eine intmax_t analysieren, überprüfen Sie für einen Fehler von strtoimax(), und dann sehen, auch wenn es „passt“ in einem pid_t durch Gießen und es auf den ursprünglichen intmax_t Wert verglichen wird.

#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;
  ...
}

Es ist nicht möglich scanf() zu verwenden, da (wie ich in einem Kommentar sagte) scanf() nicht erkennen, überläuft . Aber ich war falsch zu sagen, dass keine der strtoll() bezogenen Funktionen eine intmax_t nimmt; strtoimax() tut!

Es wird auch nicht funktionieren, irgendetwas anderes als strtoimax() zu verwenden, wenn Sie die Größe Ihrer Integer-Typ kennen (pid_t, in diesem Fall).

Andere Tipps

Es hängt davon ab, wie genau tragbar Sie sein möchten. POSIX sagt, dass pid_t ein Integer-Typ zum Speichern von Prozess-IDs und Prozessgruppe IDs verwendet signiert ist. In der Praxis könnte man mit Sicherheit davon ausgehen, dass long groß genug ist. Gelingt das nicht, muss Ihr intmax_t groß genug sein, um (so wird es jede gültige pid_t akzeptieren); Das Problem ist, könnte diese Art Werte annehmen, die nicht legitim in pid_t sind. Sie sind zwischen einem Felsen und einem harten Platz fest.

Ich würde verwenden long und nicht sehr viel Sorgen um es mit Ausnahme eines obskuren Kommentar irgendwo, dass ein Software-Archäologe von 100 Jahren wird daher finden und beobachten gibt einen Grund, warum die 256-Bit-CPU zum Stillstand Knarren, wenn ein 512 übergeben -Bit-Wert als pid_t.

POSIX 1.003,1-2.008 ist jetzt im Internet verfügbar (alle 3872 Seiten davon, in PDF und HTML). Sie müssen (kostenlos) registrieren. Ich habe es aus der Open Group Buchhandlung .

Alles, was ich sehe, es ist, dass es ein signierter Integer-Typ sein muss. Natürlich werden alle gültigen signierten Integer-Werte passen in intmax_t. Ich kann keine Informationen in <inttypes.h> oder <unistd.h> finden, die PID_T_MAX oder PID_T_MIN oder andere solche Werte gibt (aber ich habe nur gerade an diesem Abend bekam Zugang zu ihm, so könnte es versteckt werden, wo ich nicht für sie ausgesehen haben). OTOH, wird ich von meinem ursprünglichen Kommentar stehen - ich glaube, dass 32-Bit-Werte pragmatisch angemessen sind, und ich würde auf jeden Fall verwenden long, die 64-Bit auf 8-Bit-Maschinen wäre. Ich nehme an, dass etwa das Schlimmste, was passieren könnte, ist, dass ein ‚in geeigneter Weise privilegiert‘ -Prozess Wert gelesen, der zu groß war, und schickte wegen einer Nichtübereinstimmung von Typen ein Signal an den falschen Prozess. Ich bin nicht überzeugt, was ich darüber besorgt sein würde.

... oooh! ... p400 unter <sys/types.h>

  

Die Umsetzung soll eine oder mehr Programmierumgebungen unterstützen, in denen die Breiten   von blksize_t, pid_t, size_t, ssize_t und suseconds_t sind nicht größer als die Breite des Typs lang.

Wenn Sie wirklich besorgt sind, können Sie _assert(sizeof(pid_t) <= long) oder welcher Art auch immer Sie für Ihre ‚%‘ Sachen wählen.

Wie in erklärt diese Antwort , sagt der spec signed int. Wenn 'int' ändert, Ihr '% u' definitions Änderungen mit sich.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top