Programmiersprache C/C++

Umwandlung Zeichenkette - Zahl

Die anschließenden Betrachtungen sind aus folgendem Blickwinkel zu sehen:
Es ist eine Zahl einzulesen und sicherzustellen, daß es sich bei dem eingegebenem wirklich um eine Zahl gehandelt hat.
Die einzulesende Zahl wird zunächst als Zeichenkette übernommen. Danach ist die Korrektheit der Eingabe zu prüfen:
Die Eingabe ist nur dann korrekt, wenn die Zeichenkette das Literal genau einer Zahl enthält.

Umwandlung Zeichenkette - ganze Zahl

Für das Auslesen einer ganzen Zahl aus einer Zeichenkette kommen folgende Funktionen in Frage:

atoi liefert als Funktionswert die ausgelesene ganze Zahl.
atoi bricht die Erkennung ab, wenn ein Zeichen erreicht wird, welches im Literal einer ganzen Zahl nicht auftreten kann.
Der zurückgelieferte Wert ist undefiniert, wenn die Zeichenkette (in ihren ersten Zeichen) keine ganze Zahl enthält.
atoi ist somit nicht in der Lage, fehlerhafte Eingaben zu erkennen !

sscanf liefert als Funktionswert die Anzahl der Zahlen, die von der Zeichenkette gelesen wurden. Wie bei atoi bricht die Erkennung ab, wenn ein Zeichen erreicht wird, welches im Literal einer ganzen Zahl nicht auftreten kann.
sscanf ist somit nur dann in der Lage, fehlerhafte Eingaben zu erkennen, wenn in der Zeichenkette ein unzulässiges Zeichen vor einem zulässigen Zeichen gefunden wird.

strtol liefert als Funktionswert die ausgelesene ganze Zahl.
Auch strtol bricht die Erkennung ab, wenn ein Zeichen erreicht wird, welches im Literal einer ganzen Zahl nicht auftreten kann.
Der zweite Aufrufparameter von strtol kann jedoch Informationen über die Restzeichenkette liefern.
Ist die Restzeichenkette nicht leer, dann war die Eingabe fehlerhaft.

Für das geschilderte Problem liefert nur strtol eine zuverlässige Lösung !

Beispiel:

  #include <stdio.h>
  #include <stdlib.h>
  
  /* Umwandlung einer Zeichenkette in eine ganze Zahl */
  
  int main(void)
  {
    char str1[] = "345";
    char str2[] = "3.5";
    char str3[] = "3e5";
    char str4[] = "m45";
    char *ep1, *ep2, *ep3, *ep4;
    int i1, i2, i3, i4;
    int k1, k2, k3, k4;
  
    printf("Zeichenkette :\n\t%8s %8s %8s %8s\n", str1, str2, str3, str4);
  
    i1 = atoi(str1);
    i2 = atoi(str2);
    i3 = atoi(str3);
    i4 = atoi(str4);
    printf("atoi :\n\t%8d %8d %8d %8d\n", i1, i2, i3, i4);
  
    k1 = sscanf(str1, "%d", &i1);
    k2 = sscanf(str2, "%d", &i2);
    k3 = sscanf(str3, "%d", &i3);
    k4 = sscanf(str4, "%d", &i4);
    printf("sscanf :\n\t%8d %8d %8d %8d\n", i1, i2, i3, i4);
    printf("\t%8d %8d %8d %8d\tgelesene Zahlen\n", k1, k2, k3, k4);
  
    i1 = (int)strtol(str1, &ep1, 10);
    i2 = (int)strtol(str2, &ep2, 10);
    i3 = (int)strtol(str3, &ep3, 10);
    i4 = (int)strtol(str4, &ep4, 10);
    printf("strtol :\n\t%8d %8d %8d %8d\n", i1, i2, i3, i4);
    printf("\t%8s %8s %8s %8s\tunzulaessige Zeichen\n", ep1, ep2, ep3, ep4);
  
    return 0;
  }
Testergebnisse:
  Zeichenkette :
               345      3.5      3e5      m45
  atoi :
               345        3        3        0
  sscanf :
               345        3        3        0
                 1        1        1        0     gelesene Zahlen
  strtol :
               345        3        3        0
                         .5       e5      m45     unzulaessige Zeichen
Fehlerquellen:
Sowohl sscanf als auch strtol vermitteln über die Parameterliste Werte zurück. Beim Aufruf sind dort Adressen zu übergeben !

Umwandlung Zeichenkette - vorzeichenlose ganze Zahl

Beispiel:

 
  #include <stdio.h>
  #include <stdlib.h>
  
  /* Umwandlung einer Zeichenkette in eine vorzeichenlose ganze Zahl */
  
  int main(void)
  {
    char str1[] = "34567";
    char str2[] = "-35";
    char str3[] = "--3";
    char str4[] = "3-5";
    char *ep1, *ep2, *ep3, *ep4;
    unsigned int i1, i2, i3, i4;
    int k1, k2, k3, k4;
  
    printf("Zeichenkette :\n\t%8s %8s %8s %8s\n", str1, str2, str3, str4);
  
    i1 = atoi(str1);
    i2 = atoi(str2);
    i3 = atoi(str3);
    i4 = atoi(str4);
    printf("atoi :\n\t%8u %8u %8u %8u\n", i1, i2, i3, i4);
  
    k1 = sscanf(str1, "%d", &i1);
    k2 = sscanf(str2, "%d", &i2);
    k3 = sscanf(str3, "%d", &i3);
    k4 = sscanf(str4, "%d", &i4);
    printf("sscanf %%d :\n\t%8u %8u %8u %8u\n", i1, i2, i3, i4);
    printf("\t%8d %8d %8d %8d\tgelesene Zahlen\n", k1, k2, k3, k4);
  
    k1 = sscanf(str1, "%u", &i1);
    k2 = sscanf(str2, "%u", &i2);
    k3 = sscanf(str3, "%u", &i3);
    k4 = sscanf(str4, "%u", &i4);
    printf("sscanf %%u :\n\t%8u %8u %8u %8u\n", i1, i2, i3, i4);
    printf("\t%8d %8d %8d %8d\tgelesene Zahlen\n", k1, k2, k3, k4);
  
    k1 = sscanf(str1, "%[+0-9]", &i1);
    k2 = sscanf(str2, "%[+0-9]", &i2);
    k3 = sscanf(str3, "%[+0-9]", &i3);
    k4 = sscanf(str4, "%[+0-9]", &i4);
    printf("sscanf %%[+0-9] :\n\t%8u %8u %8u %8u\n", i1, i2, i3, i4);
    printf("\t%8d %8d %8d %8d\tgelesene Zahlen\n", k1, k2, k3, k4);
  
    i1 = strtol(str1, &ep1, 10);
    i2 = strtol(str2, &ep2, 10);
    i3 = strtol(str3, &ep3, 10);
    i4 = strtol(str4, &ep4, 10);
    printf("strtol :\n\t%8u %8u %8u %8u\n", i1, i2, i3, i4);
    printf("\t%8s %8s %8s %8s\tunzulaessige Zeichen\n", ep1, ep2, ep3, ep4);
  
    i1 = (unsigned int)strtoul(str1, &ep1, 10);
    i2 = (unsigned int)strtoul(str2, &ep2, 10);
    i3 = (unsigned int)strtoul(str3, &ep3, 10);
    i4 = (unsigned int)strtoul(str4, &ep4, 10);
    printf("strtoul :\n\t%8u %8u %8u %8u\n", i1, i2, i3, i4);
    printf("\t%8s %8s %8s %8s\tunzulaessige Zeichen\n", ep1, ep2, ep3, ep4);
  
    return 0;
  }
Testergebnisse mit einem 16-Bit-Compiler:
  Zeichenkette :
  	   34567      -35      --3      3-5
  atoi :
  	   34567    65501        0        3
  sscanf %d :
  	   34567    65501        0        3
  	       1        1        0        1	gelesene Zahlen
  sscanf %u :
  	   34567    65501        0        3
  	       1        1        0        1	gelesene Zahlen
  sscanf %[+0-9] :
  	   13363    65501        0       51
  	       1        0        0        1	gelesene Zahlen
  strtol :
  	   34567    65501        0        3
  	                       --3       -5	unzulaessige Zeichen
  strtoul :
  	   34567    65501        0        3
  	                       --3       -5	unzulaessige Zeichen
Umwandlung Zeichenkette - reelle Zahl

Für das Auslesen einer reellen Zahl aus einer Zeichenkette kommen folgende Funktionen in Frage:

Die nachfolgenden Betrachtungen erfolgen aus der folgenden Sicht:
Eine einzulesende Zahl wird als Zeichenkette übernommen. Die Eingabe ist nur dann korrekt, wenn die erhaltene Zeichenkette das Literal genau einer ganzen Zahlen enthält.

atof liefert als Funktionswert die ausgelesene reelle Zahl.
atof bricht die Erkennung ab, wenn ein Zeichen erreicht wird, welches im Literal einer reellen Zahl nicht auftreten kann.
Der zurückgelieferte Wert ist undefiniert, wenn die Zeichenkette (in ihren ersten Zeichen) keine reelle Zahl enthält.
atof ist somit nicht in der Lage, fehlerhafte Eingaben zu erkennen !

sscanf liefert als Funktionswert die Anzahl der Zahlen, die von der Zeichenkette gelesen wurden. Wie bei atof bricht die Erkennung ab, wenn ein Zeichen erreicht wird, welches im Literal einer reellen Zahl nicht auftreten kann.
sscanf ist somit nur dann in der Lage, fehlerhafte Eingaben zu erkennen, wenn in der Zeichenkette ein unzulässiges Zeichen vor einem zulässigen Zeichen gefunden wird.

strtod liefert als Funktionswert die ausgelesene reelle Zahl.
Auch strtod bricht die Erkennung ab, wenn ein Zeichen erreicht wird, welches im Literal einer reellen Zahl nicht auftreten kann.
Der zweite Aufrufparameter von strtod kann jedoch Informationen über die Restzeichenkette liefern.
Ist die Restzeichenkette nicht leer, dann war die Eingabe fehlerhaft.

Für das geschilderte Problem liefert nur strtod eine zuverlässige Lösung !

Beispiel:

  #include <stdio.h>
  #include <stdlib.h>                /* ist wesentlich !!! */
  
  /* Umwandlung einer Zeichenkette in eine reelle Zahl 
     mit doppelter Genauigkeit */
  
  int main(void)
  {
    char str1[] = "345";
    char str2[] = "3e4";
    char str3[] = "3-4";
    char str4[] = "m45";
    char *ep1, *ep2, *ep3, *ep4;
    double d1, d2, d3, d4;
    int k1, k2, k3, k4;
  
    printf("Zeichenkette :\n\t%8s %8s %8s %8s\n", str1, str2, str3, str4);
  
    d1 = atof(str1);
    d2 = atof(str2);
    d3 = atof(str3);
    d4 = atof(str4);
    printf("atof :\n\t%8.1lf %8.1lf %8.1lf %8.1lf\n", d1, d2, d3, d4);
  
    k1 = sscanf(str1, "%f", &d1);
    k2 = sscanf(str2, "%f", &d2);
    k3 = sscanf(str3, "%f", &d3);
    k4 = sscanf(str4, "%f", &d4);
    printf("sscanf %%f :\n\t%8.1lf %8.1lf %8.1lf %8.1lf\n", d1, d2, d3, d4);
    printf("\t%8d %8d %8d %8d\tgelesene Zahlen\n", k1, k2, k3, k4);
  
    k1 = sscanf(str1, "%lf", &d1);
    k2 = sscanf(str2, "%lf", &d2);
    k3 = sscanf(str3, "%lf", &d3);
    k4 = sscanf(str4, "%lf", &d4);
    printf("sscanf %%lf :\n\t%8.1lf %8.1lf %8.1lf %8.1lf\n", d1, d2, d3, d4);
    printf("\t%8d %8d %8d %8d\tgelesene Zahlen\n", k1, k2, k3, k4);
  
    d1 = strtod(str1, &ep1);
    d2 = strtod(str2, &ep2);
    d3 = strtod(str3, &ep3);
    d4 = strtod(str4, &ep4);
    printf("strtod :\n\t%8.1lf %8.1lf %8.1lf %8.1lf\n", d1, d2, d3, d4);
    printf("\t%8s %8s %8s %8s\tunzulaessige Zeichen\n", ep1, ep2, ep3, ep4);
  
    return 0;
  }
Testergebnisse:
  Zeichenkette :
  	     345      3e4      3-4      m45
  atof :
  	   345.0  30000.0      3.0      0.0
  sscanf %f :
  	   345.0  30000.0      3.0      0.0
  	       1        1        1        0	gelesene Zahlen
  sscanf %lf :
  	   345.0  30000.0      3.0      0.0
  	       1        1        1        0	gelesene Zahlen
  strtod :
  	   345.0  30000.0      3.0      0.0
  	                        -4      m45	unzulaessige Zeichen

Zurück zum Menü
Zurück zur vorigen Seite Weiter zur nächsten Seite

P. Böhme, 13.02.1996