mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik scanf liest bei mir nur Zahlen ein.wieso?


Autor: Timea K. (elektroatoemli7)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hallo erstmal...
Ich bin neu hier und Anfängerin im programmieren.

Funktion:
Mein Programm sollte von einem Spannungsteiler und einer 
Ersatzspannungsquelle mit Hilfe von U, Uo und Ri die 
Spannungsteiler-Widerstände R1 und R2 ausrechnen.

Frage:
Normalerweise gibt man für U einen ganzen Zahlenwert ein. Falls man sich 
jedoch vertippen sollte und keine Zahl sondern ein Zeichen eingibt, 
schliesst sich das Konsolenfenster ohne eine weitere Eingabe. Jedoch 
würde ich gerne eine Fehlermeldung rausgeben und die Abfrage 
wiederholen. (Es sind alle Zeichen von 0 bis 9 erlaubt. Der Rest von der 
ASCII-Tabelle sollte als Fehler erkennt werden...)

Und ich programmiere auf dem Dev-C 4.9.9.2 in der C-Sprache.

Also hier mal ein Teil meines Programms:

int main()
{
    int U, Ri, Uo;
    float R1, R2;

    printf("Geben Sie einen Wert fuer U in Volt ein:/t);
    scanf("%i", &U);

    ...

    system ("PAUSE");
    return(0);
}

Irgendwie komme ich nicht auf einen grünen Zweig und hoffe, dass ihr mir 
helfen könnt. (Falls ihr mehr von meinem Programm benötigt, ergänze ich 
es gerne :-) )

MFG elektroatoemli7

Autor: Honkmichi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Weil du ihm mit %i gesagt hast das er nur Zahlen (integer) einlesen 
soll!

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
scanf ist für eine fehlertolerante, robuste Eingabe nicht besonders gut 
geeignet.

Am besten geht noch, wenn du dir den Returnwert von scanf mal ansiehst. 
Dort teilt dir scanf mit, wieviele Argumente korrekt eingelesen werden 
konnten.

Wenn es aber wirklich sauber und robust sein soll, dann ist die beste 
Methode immer noch:
  Die Eingabezeile in einen String einlesen.
  Diesen String analysieren, ob falsche Zeichen darin vorkommen
  Wenn soweit alles in Ordnung ist, den String zb mit sscanf zerlegen.
  Ist man aber erst mal soweit, dann wird man die Zerlegung auch nicht
  mehr mit scanf machen, sondern eigene Routinen darauf loslassen.
  Einem Benutzer möchte man nämlich auch ganz gerne mitteilen, welches
  der 5 Argumente fehlerhaft war und nicht nur das die Eingabe fehler-
  haft ist.

scanf ist gut für Quick & Dirty Lösungen, wenns nicht auf besondere 
Robustheit ankommt.

Autor: Micky (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mein Vorschlag: scanf hat doch einen Return-Wert.
Den solltest Du auf jeden Fall auswerten.

Autor: Mark Brandis (markbrandis)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Zum Beispiel so:
#include <stdio.h>
#include <stdlib.h>

int main()
{
    int U;
    int retval;
    int input_success = 0;

    while(input_success == 0)
    {
        printf("Geben Sie einen Wert fuer U in Volt ein: ");
        fflush(stdin);
        retval = scanf("%d", &U);
        if(retval == 1)
          input_success = 1;
    }
    
    printf("Sie gaben ein: %d\n", U);
    system ("PAUSE");
    return(0);
}


Wobei es wohl nicht garantiert ist, dass fflush() den Eingabepuffer 
löscht. Bei mir (gcc Version 3.4.5 auf Intel X86 PC) tut's soweit.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mark Brandis schrieb:
> Zum Beispiel so:

machs nicht so kompliziert

   do {
     printf("Geben Sie einen Wert fuer U in Volt ein: ");
   } while( scanf("%d", &U) != 1 );

tuts auch.

Autor: Mark Brandis (markbrandis)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb:
> tuts auch.

...und ist für eine Anfängerin viel besser verständlich. ;-)
Oh, und gibt bei mir eine Endlosschleife wenn keine Zahl eingegeben 
wird. Leicht suboptimal :-)
fflush() hilft, aber manche sagen das sei böse:
http://www.gidnetwork.com/b-57.html

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mark Brandis schrieb:
> Karl heinz Buchegger schrieb:
>> tuts auch.
>
> ...und ist für eine Anfängerin viel besser verständlich. ;-)
> Oh, und gibt bei mir eine Endlosschleife wenn keine Zahl eingegeben
> wird. Leicht suboptimal :-)

LOL (schon lange nichts mehr mit scanf gemacht)
Das tut deine Lösung allerdings auch :-)
(fflush ist für Eingabestreams nicht definiert, wie du weiter oben schon 
sagtest).

Die ganze Eingabe mittels scanf ist eigentlich ziemlicher Müll, wie 
schon gesagt und nur geeignet, wenn man kontrollieren kann was daher 
kommt. In allen anderen Fällen ist dieses zumindest ein bischen besser:
   char inLine[30];

   do {
     printf("Geben Sie einen Wert fuer U in Volt ein: ");
     fgets( inLine, sizeof( inLine ), stdin );
   } while( sscanf( inLine, "%d", &U) != 1 );

Autor: Timea K. (elektroatoemli7)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
oh, danke viel mal, für so viele Antworten in dieser kurzen Zeit!!! Ich 
werde das mal ausprobieren.

:-)

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
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.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.