Ich habe einige Zeit im Internet gesucht, aber in meinen Augen keine einfache Lösung für ein wirklich einfaches Problem gefunden. Ich denke, es wurde bereits gefragt:

Ich lese einen Wert wie 20.1 oder XYZ über sscanf aus einer Datei und speichere ihn in char *width_as_string.

Alle Funktionen sollten in -std=c99 gültig sein.

Jetzt möchte ich überprüfen, ob der Wert in width_as_string eine Ganzzahl ist. Wenn true, sollte es in int width gespeichert werden. Wenn false, sollte width beim Wert 0 bleiben.

Meine Ansätze:

int width = 0;
if (isdigit(width_as_string)) {
    width = atoi(width_as_string);
}

Alternativ können Sie width_as_string in int width konvertieren und wieder in eine Zeichenfolge konvertieren. Vergleichen Sie dann, ob es dasselbe ist. Aber ich bin mir nicht sicher, wie ich das erreichen soll. Ich habe bereits itoa ausprobiert.

Funktionen wie isdigit und itoa sind in std=c99 nicht gültig, daher kann ich sie nicht verwenden.

Vielen Dank.

c
0
michithebest 26 Dez. 2015 im 16:24

3 Antworten

Beste Antwort

Lesen Sie sorgfältig einige Dokumentationen von sscanf. Es gibt eine Anzahl zurück und akzeptiert den Konvertierungsspezifizierer %n, um die Anzahl der bisher gescannten Zeichen (Bytes) anzugeben. Vielleicht möchten Sie:

int endpos = 0;
int width = 0;
if (sscanf(width_as_string, "%d %n", &width, &endpos)>=1 && endpos>0) {
  behappywith(width);
};

Vielleicht möchten Sie nach endpos>0 auch && width_as_string[endpos]==(char)0 hinzufügen (um zu überprüfen, ob die Zahl möglicherweise mit einem Leerzeichen versehen ist und dann das Ende der Zeichenfolge erreicht).

Sie können auch den Standard strtol in Betracht ziehen, der einen Endzeiger festlegt:

char*endp = NULL;
width = (int) strtol(width_as_string, &endp, 0);
if (endp>width_as_string && *endp==(char)0 && width>=0) {
  behappywith(width);
}

Das *endp == (char)0 testet, dass das mit strtol gefüllte Ende des Zahlenzeigers das Ende des Zeichenfolgenzeigers ist (da eine Zeichenfolge mit einem Null-Byte abgeschlossen wird). Sie könnten das ausgefallener machen, wenn Sie nachgestellte Leerzeichen akzeptieren möchten.

PS. Tatsächlich müssen Sie genau angeben, was eine akzeptable Eingabe ist (möglicherweise durch einige EBNF -Syntax). Wir wissen nicht, ob "1 " oder "2!" oder "3+4" für Sie akzeptabel sind (als C-Zeichenfolgen).

1
Basile Starynkevitch 26 Dez. 2015 im 19:54

Wie wäre es mit strtol?

Dies gibt einen klaren Rückgabewert, wenn etwas schief geht. Ich denke, das ist, wonach Sie suchen

http://www.cplusplus.com/reference/cstdlib/strtol/

1
Houbie 26 Dez. 2015 im 13:27

Tatsächlich können Sie ganz am Anfang sscanf verwenden, um zu überprüfen, ob die Zahl eine Ganzzahl ist oder nicht. Etwas wie das

 #include <stdio.h>
 #include <string.h>

 int 
 main (int argc, char *argv[])
 {
    int wc; // width to check
    int w; // width

    char *string = "20.1";

    printf("string = %s\n", string);

    if (strchr(string, '.') != NULL)
    {
        wc = 0;
        printf("wc = %d\n", wc);
    }
    else if ((sscanf(string, "%d", &w)) > 0)
    {
        wc = w;
        printf("wc = %d\n", wc);    
    } else w = 0;

    return 0;
}

Dies ist natürlich ein Beispielprogramm, das zuerst die Zeichenfolge nach einem "." Durchsucht. Um zu überprüfen, ob die Zahl float sein kann, und sie in einem solchen Fall zu verwerfen, wird versucht, eine Ganzzahl zu lesen, wenn kein "." gefunden werden.

Dank des Vorschlags von ameyCU geändert

Referenzseite für sscanf

1
ThCP 26 Dez. 2015 im 14:07