Forum: Compiler & IDEs sscanf, printf und stdout, stdin


von Daniel P. (callmed)


Lesenswert?

Hi,

ich benutzte WinAVR und einen ATmega32.
Habe seit gestern die printf-Ausgabe geschaft -> stdout richtig 
umgeleitet. Nun will ich in der "while(1)"-Schleife innerhalb der ersten 
2s abfragen ob ein 'h' über die USART geschickt wird (Timer funktioniert 
über COMPARE-ISR ohne Probleme).
Ich habe versucht:

static FILE mystdout = FDEV_SETUP_STREAM( uart_putchar, NULL, 
_FDEV_SETUP_WRITE );

//TIMER-ISR bei Überlauf, SET MODE -> N

int main(void)
{
  stdout = stdin = &mystdout;
        char IN;
.
.
        while(1)
        {
          sscanf(stdin, "%c", &IN);
          if (IN== 'h')
            //STOP TIMER, SET MODE -> H
          .
          .
          .
        }
.
.
.

Mein Problem ist jetzt: Der Timer läuft in die ISR obwohl die Eingabe 
innerhalb der Zeit erfolgt.

Danke schon mal im vorraus

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Nimm lieber fgets() in einen Puffer und dann sscanf() auf den Puffer.
Die ganzen Implikationen von scanf() direkt auf stdin, zusammen mit
den möglichen oder nicht möglichen Varianten von Pufferung bei stdin
sind unüberschaubar.

von Daniel P. (callmed)


Lesenswert?

Hi,

danke für die Antwort. So, wie ich deinen Text verstehe würde es nun in 
etwa so aussehen ...

************************************************************************ 
*****
...

char Command[10];

...

fgets(Command,10,stdin);
sscanf(Command,"Akt. Zeit eingeben: 2x 2x 2x", hours, minutes, seconds);

...
************************************************************************ 
*****

... für die Eingabe der Zeit? Im konrekten geht es mir nämlich um das 
Einlesen der Uhrzeit um sie an die RTC (PCF8583) weiterzuschicken.

Danke!

von Karl H. (kbuchegg)


Lesenswert?

Erwartest du wirklich, dass dein Benutzer eintippt

"Aktuelle Zeit eingeben: 12 23 50"

fgets holt einen String von stdin und sscanf zerlegt ihn in Einzelteile.
Wenn du vorher eine Eingabeaufforderung dort stehen haben willst, dann 
musst du die voerher mit printf ausgeben. Dein Benutzer wird die nicht 
für dich eingeben.

Schau dir nochmal die Umleitung deiner Streams an.

  stdout = stdin = &mystdout;

Aha, beide Standardstreams, stdout und stdin, laufen also über mystdout.

static FILE mystdout = FDEV_SETUP_STREAM( uart_putchar, NULL,
_FDEV_SETUP_WRITE );



Ooops. Wie bitte soll den von diesem Stream gelesen werden, wenn der 
Stream nur eine Funktion uart_putchar hat, welche, dem Namen nach zu 
urteilen, lediglich ein einzelnes Zeichen ausgeben, also schreiben 
kann.


Ganz ehrlich?
Vergiss den ganzen Quatsch mit der Stream Umleiterei. Das ist den 
Aufwand so nicht wert. Hol dir vom Fleury die UART Lib, damit wirst du 
glücklicher, als wie wenn du printf und scanf oder fgets benutzen 
kannst.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Karl heinz Buchegger wrote:

> Vergiss den ganzen Quatsch mit der Stream Umleiterei. Das ist den
> Aufwand so nicht wert. Hol dir vom Fleury die UART Lib, damit wirst du
> glücklicher, als wie wenn du printf und scanf oder fgets benutzen
> kannst.

Wobei sich beides wohl nicht gegenseitig ausschließt, oder?  Man kann
stdin auf den Funktionen dieser Bibliothek aufsetzen.

Was ich aber generell (nicht nur auf einem AVR, auch auf einem PC)
nicht machen würde, ist scanf() direkt zu benutzen, ohne vorher die
Daten in einen Zeilenpuffer einzulesen.

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.