Umwandlung Zeichenkette - ganze Zahl
Für das Auslesen einer ganzen Zahl aus einer Zeichenkette kommen folgende Funktionen in Frage:
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: 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 ZeichenUmwandlung Zeichenkette - reelle Zahl
Für das Auslesen einer reellen Zahl aus einer Zeichenkette kommen folgende Funktionen in Frage:
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