Hallo, ich bekomme von meinem Frequenzzähler via BUS folgenden String: FA +0010.00001587E+06 Per strtok setze ich einen pointer auf die 1 und versuche dann die Zahl mit allen Stellen einzulesen. -> long double strip_answer(char *answer, char *para) { char delimiter[] = " +"; char *ptr; long double value; fprintf(stderr,"Answer %s", answer); ptr = strtok(answer, delimiter); if(! strcmp(ptr,para)) { fprintf(stderr,"Abschnitt gefunden: %s\n", ptr); ptr = strtok(NULL, delimiter); sscanf(ptr,"%LG",&value); fprintf(stderr,"Ausgabe %LG\n\r", value); } return value; } -> Answer FA +0010.00001520E+06 Abschnitt gefunden: FA Ausgabe 10 -> Wo ist mein Denkfehler? Gruß Andreas
Der zweite strtok-Aufruf ersetzt das + hinter dem E durch '\0'.
Andreas F. schrieb: > Hallo, > > ich bekomme von meinem Frequenzzähler via BUS folgenden String: > > FA +0010.00001587E+06 > Per strtok setze ich einen pointer auf die 1 und versuche dann die Zahl > mit allen Stellen einzulesen. Du setzt ihn nicht auf die 1, sondern auf die erste 0, was aber nichts macht. Das Problem ist, dass du an allen Leerzeichen und allen +-Zeichen eine Trennung machst, also bekommt strtok als String übergeben: "0010.00001587E", denn nach dem E steht ein +. Also bekommt es als Ergebnis 10.00001587 raus, da die Zehnerpotenz fehlt. Warum machst du überhaupt das + weg? Das stört doch gar nicht.
Ein
1 | sscanf(answer, "FA%Lf", &value); |
sollte reichen. Die Formatspecifier e,f und g sind bei scanf identisch Sonst gibt es auch noch strtold Aber warum überhaupt ein long double? Der Zahlenwert mit der Genauigkeit passt noch in ein double
:
Bearbeitet durch User
Dirk B. schrieb: > Aber warum überhaupt ein long double? > Der Zahlenwert mit der Genauigkeit passt noch in ein /double/ Abgesehen davon kann es je nach verwendetem Betriebssystem und Plattform sein, dass double und long double sowieso das gleiche sind.
:
Bearbeitet durch User
@Rolf & Stefan Jopp, danke @Dirk & Rolf long double zum testen, weil ich mir nicht sicher war, wo mein Fehler lag. sscanf(answer, "FA%Lf", &value); Jein, Ja, funktioniert: Nein. Weil ich die Routine modular halten will und bei den Antworten vom Bus schauen muss was im Header steht, (FA/FB/FC für die 3 Eingänge des Counters oder Pegel beim SA/Meßsender. Gruß Andreas
Na dann
1 | char kanal; |
2 | sscanf(answer, "F%c%Lf", &kanal, &value); |
In kanal steht dann 'A', 'B' oder 'C'. Und wenn nicht, liegt ein Fehler vor. Oder
1 | char kanal[3]; |
2 | sscanf(answer, "%2s%Lf", kanal, &value); |
Dann halt mit "FA", "FB" oder "FC" Es bleibt bei einem Einzeiler. Unterschätze nicht die Macht von scanf
Dirk B. schrieb: > Na dann >
1 | > char kanal; |
2 | > sscanf(answer, "F%c%Lf", &kanal, &value); |
> In kanal steht dann 'A', 'B' oder 'C'. > Und wenn nicht, liegt ein Fehler vor. > > Oder >
1 | > char kanal[3]; |
2 | > sscanf(answer, "%2s%Lf", kanal, &value); |
> Dann halt mit "FA", "FB" oder "FC" > > Es bleibt bei einem Einzeiler. > Unterschätze nicht die Macht von scanf Ja, weil es für den einen Fall funktioniert. Nein, weil ich das als Standardroutine für alle GPIB read haben will. Aufbau ist HH +DDDDDDDD.DDDD[cr\LF] Wobei HH dann z.b 'DU', FA, AT sein kann, je nach Meßgerät und Funktion, Die Funktion muss ich eh noch erweitern, weil die Antwort beim bei einem DDS Arbitrary Funktionsgenerator deutlich komplexer ist. Gruß Andreas
bazo schrieb: >> char kanal[3]; >> sscanf(answer, "%2s%Lf", kanal, &value);> Dann halt mit "FA", "FB" oder "FC" >> >> Es bleibt bei einem Einzeiler. >> Unterschätze nicht die Macht von scanf > > Ja, weil es für den einen Fall funktioniert. > > Nein, weil ich das als Standardroutine für alle GPIB read haben will. > Aufbau ist HH +DDDDDDDD.DDDD[cr\LF] Passt doch. In kanal steht dann das HH Man kann den Formatstring auch noch anpassen, wenn es mehr als zwei H sind.
:
Bearbeitet durch User
Das Problem von strtok ist, dass es den String verändert (an die Position vom Delimiter wird ein '\0' geschrieben. Und es ist nicht reentrant/threadsafe. Wenn in einer der rufenden/parallelen Funktionen noch eine nicht abgeschlossenen strtok-Suche offen ist, geht das in die Hose.
Dirk B. schrieb: > bazo schrieb: >>> char kanal[3]; >>> sscanf(answer, "%2s%Lf", kanal, &value);> Dann halt mit "FA", "FB" oder "FC" >>> >>> Es bleibt bei einem Einzeiler. >>> Unterschätze nicht die Macht von scanf >> >> Ja, weil es für den einen Fall funktioniert. >> >> Nein, weil ich das als Standardroutine für alle GPIB read haben will. >> Aufbau ist HH +DDDDDDDD.DDDD[cr\LF] > > Passt doch. In kanal steht dann das HH > > Man kann den Formatstring auch noch anpassen, wenn es mehr als zwei H > sind. Auch wenn die Anzahl der Parameter und das Trennzeichen sich unterscheidet? Mittels strtok kann ich solange die Antwort durchlaufen, bis ich alle Parameter habe. Dirk B. schrieb: > Das Problem von strtok ist, dass es den String verändert (an die > Position vom Delimiter wird ein '\0' geschrieben. > > Und es ist nicht reentrant/threadsafe. > Wenn in einer der rufenden/parallelen Funktionen noch eine nicht > abgeschlossenen strtok-Suche offen ist, geht das in die Hose. Das trifft hier nicht zu, es wird über die Funktion aus der libgpip oder direkt von /dev/usbtmc die Antwort gelesen und dann die Antwort zerlegt, das ganze in einem Programm. Und selbst wenn ich aus dem Auslesen jemalss ein eigenen Thread mache, Schnittstelle ist immer record.xyz. Der Stringinhalt ist danach eh obsolet. Überschrieben, weil ich den Wert zyklisch auslese. Überschrieben, weil ich den nächsten Query absetze. Oder die Routine wird dann irgendwann durch den User wieder aufgerufen, daa wir das eh neu vom Bus eingelesen. Gruß Andreas PS: Gibt es in C eine Funktion, die analog zu int main(int argc, char *argv[] funktioniert? Aufrufen mit einem String und in der Funktion bekommt man die einzelnen Argumente aufgedröselt geliefert?
bazo schrieb: > PS: > Gibt es in C eine Funktion, die analog zu int main(int argc, char > *argv[] funktioniert? Aufrufen mit einem String und in der Funktion > bekommt man die einzelnen Argumente aufgedröselt geliefert? Das macht nicht die Funktion sondern das Betriebssystem bzw. der Startupcode. Möchtest du eine variable Anzahl Argumente benutzen? Man kann das aber mit scanf und einer Schleife hinbekommen.
:
Bearbeitet durch User
Dirk B. schrieb: > bazo schrieb: >> PS: >> Gibt es in C eine Funktion, die analog zu int main(int argc, char >> *argv[] funktioniert? Aufrufen mit einem String und in der Funktion >> bekommt man die einzelnen Argumente aufgedröselt geliefert? > > Das macht nicht die Funktion sondern das Betriebssystem bzw. der > Startupcode. > > Möchtest du eine variable Anzahl Argumente benutzen? > > Man kann das aber mit scanf und einer Schleife hinbekommen. Ja, nur weiss ich nicht, ob ich immer die erwartete Anzahl an Parameter zurückbekomme und die Reihenfolge ob String oder numerisch ist völlig frei: vom DDS Arbitrary Funktionsgenerator z.b. BSWV WVTP, SINE,FRQ,100HZ,PERI,0.01S,AMP,2V,OFST,0V,HLEV,1V,LLEV,-1V,PHSE,0 Vom Zähler/den einem SA halt obiges HH DDDD.DDDDE0x Den zweite SA/Bolometer habe ich noch nicht angeschaut Als Trennzeichen habe ich je nach dem " ",";",",",:" Der Grundaufbau ist immer gleich, - Bedienoberfläche für die wichtigsten Einstellungen - Capture des aktuellen Bildes - Kurvenschreiber (Datenlogger)
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.