Forum: Compiler & IDEs scanf stürzt bei seriellem Port ab


von Stefan F. (sfrings)


Lesenswert?

Mein mißratener Code sieht so aus:

int number;

int main(void) {
    // initialize the serial port
    initserial();
    // switch LED on
    DDRB |= (1<<PB2);
    PORTB &= ~(1<<PB2);
    // mail loop
    while (1) {
        printf("Enter a number\r\n");
        scanf("%d",&number);
        printf("You entered: %d\r\n",number);
    }
}

Die initserial() Funktion initialisiert den seriellen Port und verbindet 
stdin und stdout damit.

Problem 1:
Sobald ich einen Buchstaben eingebe, scheint das Programm abzustürzen
und sich selbst zu zerstören. Denn nach Strom aus und wieder an geht
nichtmal die LED an. Ich muss dann den Controller neu flashen. Und das
passiert immer, 100% reproduzierbar.  Was ist denn hier falsch?

Problem 2:
Nach Abschluss der Eingabe (\n), müsste scanf abbrechen und dieses 
Zeichen im Puffer belassen. Der zweite und alle folgenden Aufrufe 
müssten also immer wieder abbrechen ohne daß überhaupt auf weitere 
Eingaben gewartet wird - denn ich entferne dieses Zeichen ncith aus dem 
Puffer. Stattdessen verschwindet das Newline Zeichen wie von Geisterhand 
aus dem Puffer, obwohl in der Doku der avr-libc genau das Gegenteil 
ausdrücklich geschrieben steht.

von gast (Gast)


Lesenswert?

poset mal deine init!

von Michael A. (micha54)


Lesenswert?

Hallo,

die scanf() benötigt ein File, welches die Funktion ungetc() 
unterschtützt. unget() legt das letzte Zeichen zurück in __file->unget 
und setzt ein flag, damit das mächste getch() es auch zuerst dort 
abholt.

Daraus ergeben sich die Fragen:
 - wie sind deine streams initialisiert ?
 - hast Du ggf. eigene getch() geschrieben, die unget() nicht 
unterstützen ?

Gruß,
Michael

von Karl H. (kbuchegg)


Lesenswert?

Stefan Frings wrote:

> Nach Abschluss der Eingabe (\n), müsste scanf abbrechen und dieses
> Zeichen im Puffer belassen. Der zweite und alle folgenden Aufrufe
> müssten also immer wieder abbrechen ohne daß überhaupt auf weitere
> Eingaben gewartet wird - denn ich entferne dieses Zeichen ncith aus dem
> Puffer. Stattdessen verschwindet das Newline Zeichen wie von Geisterhand
> aus dem Puffer, obwohl in der Doku der avr-libc genau das Gegenteil
> ausdrücklich geschrieben steht.

Ich hab jetzt nicht die Doku gecheckt.
Aber deine Beschriebung dessen, was scanf beim Einlesen von Zahlen 
machen soll, stimmt so nicht.

Das wurde auch in deinem ursprünglichen Thread schon mal angesprochen: 
Vergiss scanf! Für mehr als ein paar Testprogramme zum persönlichen 
Gebrauch ist das alles nicht geeignet. Wenns eine einigermassen robuste 
Eingabemethode sein soll, die nicht gleich bei jedem falschen Zeichen 
ausser Tritt kommt, führt zunächst mal kein Weg daran vorbei, eine 
komplette Zeile als String zu lesen (mittels fgets oder was du sonst 
hast) und dann erst wenn die komplette Eingabe als String vorliegt, 
diesen String zu zerpflücken. scanf sieht auf den ersten Blick toll aus, 
weil es anscheinend wenig Arbeit macht. Aber spätestens dann, wenn du 
mit Fehlerfällen in der Eingabe klar kommen musst, ist scanf ein 'pain 
in the ass'

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
Noch kein Account? Hier anmelden.