C/C++ Aus XML-String Kommazahlen extrahieren?
-
Hey danke Artchi!
Aber der XML-Rahmen ist absolut fest. Da ändert sich nichts. Der Robo schickt immer den gleichen XML-Rahmen. Nur die Zahlen ändern sich. Was meinst Du nun?
-
Also sscan würde ich pers. garnicht benutzen, weil ich das garnicht kenne. Scheint C zu sein, oder?
TinyXML ist echt mini. Ist glaub ich auch nur Templates, muß man nicht mal bauen.
Für Regex braucht man aber auch eine zus. Library, selbst wenn es nur TR1 ist. Oder haste TR1 oder Boost? Irgendwas muß man doch noch haben, kann mir nicht vorstellen, nur mit der Stdlib klar zu kommen. Oder ist das ne Embedded-Anwendung wo man auf jedes Byte achten muß?
Wenns wirklich immer das gleiche Schema ist, dann kann man doch die Standard-Streams benutzen, oder? Funktionsweise ist ähnlich wie der obige Code, nur das man dann halt ne while-Schleife noch einbaut, und unwichtige Blöcke überspringt und mit der string-Klasse kann man ja unwichtige Infos wie =" und " entfernen, bevor die Zahl endgültig konvertiert wird.
Möchte aber behaupten, das man bei dem Aufwand evtl. mit nem Parser schneller zum Ergebnis kommt. Aber kann man ja ausprobieren, dann weiß man es selber.
Spirit wäre auch ne Möglichkeit. Aber auch eine zus. Library. Ich weiß nicht, ich bin halt eher der Typ, der sich lieber eine Library schnappt, wenns dafür was gibt.

-
Joah, ich werd mir mal Boost besorgen und mit den RegExp rumexperimentieren! Danke Artchi!
Aber die Sache mit sscanf interessiert mich dennoch, weil es sehr schlank und schnell ist, denke ich!
-
Wenn das Format immer fix ist, dann dürfte sscanf reichen. (Was aber nicht heißt, dass du dich nicht mal mit RegEx auseinandersetzen solltest :))
@Artchi
Regex sind im TR1 und der ist ja bei neuen Compilern dabei. Aber Boost würde ich auch nicht unbedingt als "extra Library" ansehen
-
matze77 schrieb:
Aber der XML-Rahmen ist absolut fest. Da ändert sich nichts.
na denn...
#include <stdio.h> #include <stdlib.h> #include <ctype.h> char *strings (char c) { static int state; static char buff[256]; static char idx; switch (state) { case 0: if (c == '\"') state = 1; break; case 1: if (c == '\"') { buff[idx] = 0; state = 0; idx = 0; return buff; } buff[idx++] = c; break; } return 0; } int main(void) { char *xml = "<Rob TYPE=\"KUKA\">" "<RIst X=\"12.6\" Y=\"234.456\" Z=\"645.79\" A=\"2.4\" B=\"456.814\" C=\"65.33\" />" "<FTC Fx=\"1.234\" Fy=\"54.75\" Fz=\"345.76\" Mx=\"2346.6\" My=\"\" Mz=\"3546\" />" "<Override>90</Override>" "<IPOC>123645634563</IPOC>" "</Rob>"; while (*xml) { char *p = strings (*xml++); if (p && (isdigit(*p) || *p==0)) { printf ("%f\n", atof(p)); } } }
-
das da oben: static char idx; ^^
sollte ein 'int' sein, kein 'char'

-
Boah! Danke Erst mal! Das muss ich mir erst mal in aller Ruhe anschauen.
Aber ... Ich habs eben mal mit Dev-C++ kompiliert und er spuckt mir nur '12.6' aus, naja ok. Nur - der XML-Rahmen enthält ja, wenn empfangen wird, "echte"
Anfürhungszeichen ("). Im Code wurden diese durch (backslash") ersetzt und dann funktioniert es ja auch einigermaßen.Frage: Wird der Backslash automatisch generiert, wenn die Daten vom Netzwerk in den Buffer, Variable geschrieben werden? Ich glaub ja nich, mmmmhh .... Wenn nicht, dann werd ich wohl nich um die RegEx drumrumkommen, oder?
-
die backslashes braucht man nur, wenn man "'s in stringkonstanten im code hat. im speicher sind sie nicht mehr vorhanden.
char *cp = "12\\34\"56\""; // <-- im speicher steht dann [b]12\34"56"[/b] die beiden äusseren "'s sind die begrenzungen des string-literalsder code^^ reagiert übrigens auf "'s und nicht auf \'s. funktioniert er unverändert bei dir?

-
Nein, ich hab noch char in int umgeschrieben, so wie feuerteufel-Fan es schrieb. Aber dann spuckt er mir auch nur 12.6 aus. Ich finde den Code von ihm ein weinig zu überdimensioniert. Da hab ich selbst mal was probiert ...
/* sscanf example */ #include <stdio.h> int main () { char sentence []="<FTC Fx=\"1.234\" Fy=\"54.75\""; float x, y; sscanf (sentence,"<FTC Fx=\"%f\" Fy=\"%f\"",&x, &y); printf ("%f, %f\n",x,y); getchar(); return 0; }Ausgabe: 1.234000, 54.750000
Und das ist auch genau was ich erstmal möchte nur das mir die Anführungszeichen in der Quelle (sentence) noch Sorgen machen.
Also Du meinst, dass was im Spiecher liegt (sentence) sind ganz normale ("). Ich muss nur noch wissen, was genau in sentence drinne steht und dann kann ich mit
sscanf(sentence, "XML-Rahmen mit Kommazahlen in Anführungszeichen", &x, &y);die Kommazahlen auslesen, oder? Ich muss nur die Anführungszeichen im XML-Code bei sscanf als (backlash") eingeben und dann liest sscanf die Kommazahlen korrekt aus dem NetzwerkEmpfangspuffer aus, oder?
-
matze77 schrieb:
Nein, ich hab noch char in int umgeschrieben, so wie feuerteufel-Fan es schrieb. Aber dann spuckt er mir auch nur 12.6 aus.
du musst nur den 'static char idx;' in 'static int idx;' ändern, dann sollte es gehen. bei mir ist die ausgabe:
12.600000 234.456000 645.790000 2.400000 456.814000 65.330000 1.234000 54.750000 345.760000 2346.600000 0.000000 3546.000000und von wegen überdimensioniert: eine vollwertiger XML-parser wäre überdimensioniert.

-
matze77 schrieb:
oder? Ich muss nur die Anführungszeichen im XML-Code bei sscanf als (backlash") eingeben und dann liest sscanf die Kommazahlen korrekt aus dem NetzwerkEmpfangspuffer aus, oder?
stell fragen zu 'sscanf' am besten im ansi-c forum

-
Tja, und mit TinyXML wäre es bestimmt nicht schneller gegangen.

-
Habt Dank, Leute!
Also, der Code von Feuerteufel funktioniert doch einwandfrei! Ich Dämlack hab getchar(); mit in die Schleife genommen, damit das ConsolenFenster offen bleibt, hehe. Deswegen nur ein Wert.
Nochmal Danke an Feuerteufel!
-
matze77 schrieb:
Nochmal Danke an Feuerteufel!
gern geschehen. vergiss aber nicht, dass der code einfach nur strings aus anführungszeichen extrahiert. sollte wider erwarten dein XML doch dynamisch sein, dann nimm bitte einen echten XML parser, z.b expat oder das, was artchi vorgeschlagen hat.
- und - fehlerteufel bitte.

-
matze77 schrieb:
Verzeihung! Ich meine dann C++. Und wie siehts damit aus?
Jetzt hast du aber C

Grüssli
-
Hehe!
Hauptsache irgendwatt!
-
Dravere schrieb:
Jetzt hast du aber C
ist doch nicht schlimm. ich wette, der code geht unverändert durch 'nen c++ compiler.
