scanf und NULL

OP #2369098
Lesenswert?
• ▲
▼
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?
Gast #2369110
Lesenswert?
• ▲
▼
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.
#2369224
Lesenswert?
• ▲
▼
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.)
#2369243
Lesenswert?
• ▲
▼
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 :-)
#2369331
Lesenswert?
• ▲
▼
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

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.