Hallo, Ich frage mit einem Mikrocontroller eine serielle Schnittstelle nach Werten ab und bekomme von der anderen Seite dann einen String, gefolgt von einem CR. Soweit so gut. Ich möchte nun auswerten ob eventuell nur ein CR zurückgegeben wurde. char str[32]; int main() { while (1) { pc.scanf ("%s",str); if (str[0]==0) { pc.printf("NULL string"); } else { pc.printf("valid string"); } }//end while 1 } Die Ausgabe "NULL String" kommt nie, besser gesagt wenn ich nur CR schicke passiert gar nichts. Woran kann das liegen?
Weil scanf Whitespace (' ' \t \r \n) überliest und solange wartet, bis ein vernünftiges Zeichen (für %s) kommt. Nimm besser fgets. Das liest alle Zeichen bis zum '\n'. NULL ist für einen Leerstring nicht korrekt.
gets erkennt dann aber nicht mein CR (\r), weil es ein LF (\n) erwartet. Problem ist es, dass das CR von einem Gerät gesendet wird, und ich keine Möglichkeit habe dies zu ändern.
David P. schrieb: > gets erkennt dann aber nicht mein CR (\r), weil es ein LF (\n) erwartet. > Problem ist es, dass das CR von einem Gerät gesendet wird, und ich keine > Möglichkeit habe dies zu ändern. Sendet das Gerät CR LF, also beide Zeichen? Wenn ja, dann filtert man das eben aus. Allerdings ist es auf µC meistens sowieso nicht so schlau, printf und scanf zu verewnden. Meistens ist man besser bedient, wenn man sich die Low-Level Schreib/Lese Funktionen selber schreibt. Sind ja auch nicht weiter wild und ein Zeilenlesen bis zu einer Endekennung ist ja kein großartiges Problem. Das Beharren auf printf/scanf verkompliziert die Sachen meistens einfach nur. (Auf Desktop Systemen sieht die Sache anders aus. Da hinter printf bzw scanf Verteiler sitzen, die zb über das Betriebssystem Stream-Redirections betreiben, macht dort das Verwenden von printf/scanf Sinn. Aber all das hat man auf einem µC ja traditionell nicht.)
Leider schickt das Gerät nur ein CR ohne LF. So wie aussieht muss ich die Routinen dann selbst schreiben. Wollte es nur umgehen weil ich dachte es sei mit scanf einfacher. Vielen Dank!
David P. schrieb: > dachte es sei mit scanf einfacher. Wenn du scharf darüber nachdenkst, kommst du drauf, dass das für dich brauchbare 'gets' in etwa so aussieht void gets( char* string ) { char c; while( ( c = pc.getc() ) != '\r' ) *string++ = c; *string = '\0'; } Das wird an Einfachheit von scanf schwer zu schlagen sein :-) OK. Mit vernünftiger Fehlerbehandlung wirds dann noch etwas komplizierter, aber scanf hat genau das gleiche Problem. Im Kern ist das schon deine Funktionalität. Da lohnt es nicht, großartige Klimmzüge mit scanf zu machen :-)
David P. schrieb: > Wollte es nur umgehen weil ich > dachte es sei mit scanf einfacher. Naja, ein wenig Kanonen auf Spatzen. ;-) Es müsste mit dem %[-Format gehen, so in der Art
1 | scanf("%20[^\r]%*c", &array); |
Das %*c überliest dabei das folgende \r.
Man sollte nie direkt von der UART lesen, da dann die CPU steht und nichts anderes machen kann. Besser richtet man einen FIFO ein, der per Interrupt die UART einliest. Und dann kann man auch gleich ein Flag setzen, wenn CR oder LF empfangen wurde. Und das Main liest erst aus dem FIFO, wenn das Flag gesetzt wurde, d.h. der String komplett ist. Peter
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.