Guten Tag! Aus einer immerwährenden Zeichenkette (RS232), z.B. ...wert82grad... soll nur die 82 in C extrahiert werden. Ich habe etliche Zeichenkettenfunktionen gefunden, aber keine, die mein Problemchen löst. Weiss jemand Rat? Hab viel Gutes über dieses Forum gehört!
Bernd Kretschmar schrieb: > soll nur die 82 in C extrahiert werden. > > Ich habe etliche Zeichenkettenfunktionen gefunden, aber keine, die mein > Problemchen löst. Mit regular Expression im Formatstring eines sscanf müsste das gehen. Jedoch hab ich keine Erfahrung mit regular Expressions. Ich machs immer traditionell: Den Anfang der Zahl suchen. Das geht ganz leicht in einer Schleife beginnend am Stringanfang solange einen Pointer erhöhen, bis man auf das erste isDigit() Zeichen stösst. Ab dort dann einen atoi() oder einen strtol() ansetzen und man hat die Zahl. Ein Programmierer muss unter anderen diese beiden Dinge beherrschen * Kentniss der Funktionen, die er zur Verfügung hat * Wie kann man mehrere Funktionen bzw. typische Programmuster kombinieren um das Gewünschte zu erhalten Ein typisches Muster in der Stringverarbeitung ist nun mal:
1 | char irgendeinString[] = "...wert82grad..."; |
2 | |
3 | // man nehme eine Pointervariable
|
4 | char* pLoop; |
5 | |
6 | // und richte es so ein, dass der Pointer auf den Anfang eines Strings zeigt
|
7 | pLoop = irgendeinString; |
8 | |
9 | // jetzt alle Zeichen des Strings durchgehen
|
10 | // und gegebenenfalls eine Aktion mit dem Zeichen durchführen
|
11 | // oder die Schleife vorzeitig abbrechen oder ...
|
12 | //
|
13 | // der springende Punkt ist, dass *pLoop das Zeichen darstellt und
|
14 | // mittels pLoop++ ein Zeichen nach dem anderen in der Schleife besucht
|
15 | // wird
|
16 | while( *pLoop && irgendeine Bedingung die das Zeichen *pLoop erfüllen soll ) |
17 | mach eventuell etwas mit dem Zeichen *pLoop |
18 | |
19 | pLoop++; |
20 | }
|
Das arbeitet alle Zeichen in einem String durch. Zb. könnte diese Schleife so lange laufen bis isDigit( *pLoop ) durch ein TRUE meldet, dass *pLoop eines der Zeichen '0', '1', '2', '3', '4', '5', '6', '7', '8' oder '9' ist. Damit wäre der Anfang der 'Zahl' im String gefunden. atoi möchte einen Pointer haben, der auf den Anfang einer 'Zahl' in einem String zeigt. Passt perfekt, genau den Pointer haben wir ja, nachdem in der Schleife der Anfang der 'Zahl' gefunden wurde.
du wist hier bestimmt keine fertige Lösung bekommen, denn du kannst dein Problem recht leicht selber lösen. ich Tippe mal, du benutzt C als Programmiersprache? Wenn ja, dann such mal nach String-Funktionen für C, oder welche Programmiersprache auch immer du benutzt.
Karl heinz Buchegger schrieb: > Ein Programmierer muss unter anderen diese beiden Dinge beherrschen > * Kentniss der Funktionen, die er zur Verfügung hat > * Wie kann man mehrere Funktionen bzw. typische Programmuster > kombinieren um das Gewünschte zu erhalten Ach! Das kommt dann wohl im zweiten Semester? ;-)
Jens Karstedt schrieb: > siehe lexer, scanner, parser Wir sind im Forum: Mikrocontroller und Elektronik, da würde ich doch eher händisch an die Sache ran gehen. Für größere µCs läuft es wohl auf strstr() und sscanf() hinaus.
Bernd Kretschmar schrieb: > Aus einer immerwährenden Zeichenkette (RS232), z.B. und wenn es ein stetiger Bytestrom ist (das interpretiere ich aus "immerwährenden") der dann in der Verarbeitung natürlich in irgendeiner Form geblockt ist, denk daran bei den Blocks für die Suche eine ausreichende Überlappung zu machen. Sprich wenn Du Dein obiges Beispiel nimmst: wert82grad und 82 wird gesucht, kann es passieren daß Du 2 Blöcke hast mit: ...wert8 2grad... dann findest Du einen String der Länge 2 nur dann, wenn Du den 2. Block mit einem Zeichen überlappst also: ...wert8 und 82grad... Allgemein: Wenn Du einen String der Länge X suchst musst Du X-1 überlappen. Aber nur zum Suchen, nicht zum weiterverarbeiten überlappen.
1 | int meine82, ret; |
2 | ret = sscanf( puffer, "%*[^0-9]%d", &meine82 ); |
3 | // ret ist 1, wenn das Lesen geklappt hat
|
Wenn ich Zahlen oder was auch immer aus ner RS232 raussuchen will/muß, mache ich das mit ner statemachine, die ich mit den Zeichen füttere die reinkommen und die mir ggf. ne fertige Zahl zurückliefert. Also im Beispiel: Zustände: SUCHE_ZAHL_BEGINN, SUCHE_ZAHL_ENDE und dann anhand der reinkommenden Zeichen die Zustände wechseln. Zeichen in Zahlen sind dann beispielsweise -+.,eE oder was auch immer. Den rausgeschnittenen Zahlenstring dann mit sscanf oder ähnlich behandeln. Ja, so könnte das gehen. Cheers Detlef
Klaus Wachtler schrieb: > int meine82, ret; > ret = sscanf( puffer, "%*[^0-9]%d", &meine82 ); > // ret ist 1, wenn das Lesen geklappt hat Gibt es zu dem Thema, also reguläre Ausdrücke mit sccanf und Co. ohne boost, irgendwo etwas zum Nachlesen? Also mit "C regexp", "sccanf reguläre Ausdrücke" und ähnlichem kam ich nicht wirklich weiter und boost muss imho nicht sein. Mein C-Buch ist auch nicht wirklich hilfreich.
Hallo dagger, in der ISO_C99 steht da einiges. Deine Frage im Abschnitt 7.19.6.2 The fscanf function Keine leichte Lektüre aber gut zum Nachschlagen ;) avr
Sorry ;( sscan ist in 7.19.6.7 The sscanf function aber : 2 The sscanf function is equivalent to fscanf, except that... also fast richtig ;) Die 3,6 MB sind scheinbar beliebt. avr
dagger schrieb: > Klaus Wachtler schrieb: >> int meine82, ret; >> ret = sscanf( puffer, "%*[^0-9]%d", &meine82 ); >> // ret ist 1, wenn das Lesen geklappt hat > Gibt es zu dem Thema, also reguläre Ausdrücke mit sccanf und Co. /ohne/ > boost, irgendwo etwas zum Nachlesen? > Also mit "C regexp", "sccanf reguläre Ausdrücke" und ähnlichem kam ich > nicht wirklich weiter und boost muss imho nicht sein. Mein C-Buch ist > auch nicht wirklich hilfreich. Daß du damit nichts findest, ist verständlich. Das liegt dran, daß es keine regulären Ausdrücke sind (auch wenn es hier gelegentlich so steht). Zu scanf: http://www.wachtler.de/ck/19_4_Liste_Funktionen.html#SECTION0002049200000000000000 Zu printf: http://www.wachtler.de/ck/19_4_Liste_Funktionen.html#SECTION0002048100000000000000
avr schrieb: > Die 3,6 MB sind scheinbar beliebt. Danke für das pdf. Naja, wenn die Suchmaschine Recht hat, ist dass der letzte frei herunterladbare C-Standard, zumindest scheint der aktuellste nur gegen Registrierung herunterladbar zu sein. Warum auch immer man sich für einen ansonsten kostenlosen Standard registrieren soll. Mano schrieb: > Bei der Manpage von scanf steht ein wenig dazu. Mist, da hätte ich auch selbst drauf kommen können, danke. Klaus Wachtler schrieb: > dagger schrieb: >> Klaus Wachtler schrieb: >>> int meine82, ret; >>> ret = sscanf( puffer, "%*[^0-9]%d", &meine82 ); >>> // ret ist 1, wenn das Lesen geklappt hat >> Gibt es zu dem Thema, also reguläre Ausdrücke mit sccanf und Co. /ohne/ >> boost, irgendwo etwas zum Nachlesen? >> Also mit "C regexp", "sccanf reguläre Ausdrücke" und ähnlichem kam ich >> nicht wirklich weiter und boost muss imho nicht sein. Mein C-Buch ist >> auch nicht wirklich hilfreich. > Daß du damit nichts findest, ist verständlich. > Das liegt dran, daß es keine regulären Ausdrücke sind (auch wenn es > hier gelegentlich so steht). Danke. Ah ok, auf deine Seite hätte ich auch kommen können... ;-)
dagger schrieb: > Naja, wenn die Suchmaschine Recht hat, ist dass der > letzte frei herunterladbare C-Standard Nö. http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1425.pdf
Stefan Ernst schrieb: > dagger schrieb: >> Naja, wenn die Suchmaschine Recht hat, ist dass der >> letzte frei herunterladbare C-Standard > Nö. > http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1425.pdf Heute klappt ja gar nichts, aber egal, der Tag ist ja bald vorbei... ;-)
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.