aus char array zwei float Zahlen auslesen

Gast #1326398
Lesenswert?
• ▲
▼
Hallo zusammen,

ich habe wieder ein C/C++ Prgrammierproblem.
1
char sResult[254];
2
//fill sResult
3

4
printf("sResult = %s\n",sResult);

sResult enthält folgendes:
1TP0.0000\n2TP0.0000
Das "\n" ist ein Zeilenumbruch.

Bei dem füllen des Arrays ist immer ein 1TP gefolgt von einer Kommazahl. 
Danach ein Zeilenumbruch und 2TP gefolgt von einer Kommazahl. Die 
Formatierung ist auch immer gleich (siehe Bsp.)
Ich möchte nun die beiden Kommazahlen in unterschiedlichen Variablen 
speichern. Wie mache ich das?
#1326409
Lesenswert?
• ▲
▼
Michael schrieb:
> Hallo zusammen,
>
> ich habe wieder ein C/C++ Prgrammierproblem.
>
>
1
> char sResult[254];
2
> //fill sResult
3
> 
4
> printf("sResult = %s\n",sResult);
5
> 
6
>
>
> sResult enthält folgendes:
> 1TP0.0000\n2TP0.0000
> Das "\n" ist ein Zeilenumbruch.
>
> Bei dem füllen des Arrays ist immer ein 1TP gefolgt von einer Kommazahl.
> Danach ein Zeilenumbruch und 2TP gefolgt von einer Kommazahl. Die
> Formatierung ist auch immer gleich (siehe Bsp.)
> Ich möchte nun die beiden Kommazahlen in unterschiedlichen Variablen
> speichern. Wie mache ich das?
1
double Zahl1, Zahl2;
2

3
sscanf( sResult, "1T%lf\n2T%lf", &Zahl1, &Zahl2 );
Gast #1326432
Lesenswert?
• ▲
▼
Vielen Dank für die schnelle Antwort.

Habe das gleich mal umgesetzt und erhalte jedoch "nur":

printf("Zahl1= %lf\n",Zahl1);
printf("Zahl2= %lf\n",Zahl2);

folgende Ausgabe:
Zahl1= 0.000000
Zahl2= 0.000000

Dies aber auch wenn z.B. nicht 0.0000 in dem char steht sondern der z.B. 
so aussieht:
1TP0.0000\n2TP0.0005
Gast #1326446
Lesenswert?
• ▲
▼
Entschuldige,

ich hatte einen Fehler und hab nicht &Zahl1,&Zahl2, sondern nur 
Zahl1,Zahl2 in sscanf eingetragen.

Allerdings ist es trotzdem (noch) nicht richtig:
printf("sResult= %s\n",sResult);
Ausgabe:
sResult= 1TP-0.0005
2TP0.0000

sscanf( sResult, "1T%lf\n2T%lf", &Zahl1, &Zahl2 );
printf("Zahl1= %lf\n",Zahl1);
printf("Zahl2= %lf\n",Zahl2);

Ausgabe:
Zahl1= 0.000000
Zahl2= 
189036386038403088057117598843902933455662669321988840590337000865846180 
376463338129764928.000000
Gast #1326491
Lesenswert?
• ▲
▼
Wenn das Programm, welches diesen String schickt korrekt programmiert 
ist (was ich hoffe), dann sollte dieser immer so aussehen und es sollten 
sich nur die beiden Zahlen ändern.

Ist es deutlich komplizierter auf variable Strings vorbereitet zu sein?
Deine Lösung ist einfacher als ich erwartet habe.
#1326504
Lesenswert?
• ▲
▼
Michael schrieb:
> Wenn das Programm, welches diesen String schickt korrekt programmiert
> ist (was ich hoffe), dann sollte dieser immer so aussehen und es sollten
> sich nur die beiden Zahlen ändern.

Das Problem, welches immer wieder mal auftritt:
Der andere Programmierer entscheidet, dass er das Protokoll leicht 
(natürlich kompatibel :-) ändert.

> Ist es deutlich komplizierter auf variable Strings vorbereitet zu sein?
> Deine Lösung ist einfacher als ich erwartet habe.

Man kann mit sscanf auch "regular Expressions" angeben. Aber damit kenne 
ich mich nicht aus.
Abgesehen davon: So kompliziert ist das auch wieder nicht, wenn man es 
händisch macht. Ob du das als 'deutlich' ansehen willst, hängt 
wahrscheinlich von dir ab. Aber mit einem 10-Zeiler wirst du nicht davon 
kommen, wenn man das wasserdicht machen will.
#1327218
Lesenswert?
• ▲
▼
echte regular expressions gehen nicht mit scanf(), aber
so etwas ähnliches:
1
  char sResult[] = "1TPTPPTPPTPTPTPT3.14159265354\n2PPPPTTT2.718281828";
2
  double    Zahl1, Zahl2;
3
  int nOk;
4

5
  nOk = sscanf( sResult, "1%*[A-Za-z]%lf 2%*[TP]%lf", &Zahl1, &Zahl2 );
6

7
  if( nOk>=1 )
8
  {
9
    printf( "Zahl1 = %f\n", Zahl1 );
10
  }
11

12
  if( nOk>=2 )
13
  {
14
    printf( "Zahl2 = %f\n", Zahl2 );
15
  }

In dem Formatstring steht die 1 für ein zu lesendes Zeichen '1' wie
gehabt.
%[A-Za-z] (ohne Stern) würde für alle Groß- und Kleinbuchstaben stehen,
also auch beliebige 'T' und 'P' in jeder Reihenfolge und alles, was
in dieser Muster packt, in ein char-Feld kopieren.

Mit einem Stern (also %*[A-Za-z]) dagegen unterbleibt das Kopieren,
die gelesenen Zeichen ('T' und 'P' z.B.) werden wegegeworfen.
%lf dann wie gehabt für eine double.
Das Leerzeichen passt ebenso als wenn ein \n stehen würde für
jedes white space, also auch \r, \t etc.
Die 2 passt auf ein Zeichen '2'.
%*[TP] liest alle Folgen aus 'T' und 'P' und wirft sie weg
(wegen des Sterns).


Und: (s)scanf liefert zurück, wieviele Umwandlungen erfolgreich
waren (wobei die mit * unterdrückten Umwandlungen nicht gezählt
werden, im besten Fall also 2).
Man sollte unbedingt diesen Rückgabewert mit den erwarteten
Umwandlungen vergleichen, um nicht mit blödsinnigen Werten
zu rechnen!

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren