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


von Timea K. (elektroatoemli7)


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

von Honkmichi (Gast)


Lesenswert?

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

von Karl H. (kbuchegg)


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.

von Micky (Gast)


Lesenswert?

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

von Mark B. (markbrandis)


Lesenswert?

Zum Beispiel so:
1
#include <stdio.h>
2
#include <stdlib.h>
3
4
int main()
5
{
6
    int U;
7
    int retval;
8
    int input_success = 0;
9
10
    while(input_success == 0)
11
    {
12
        printf("Geben Sie einen Wert fuer U in Volt ein: ");
13
        fflush(stdin);
14
        retval = scanf("%d", &U);
15
        if(retval == 1)
16
          input_success = 1;
17
    }
18
    
19
    printf("Sie gaben ein: %d\n", U);
20
    system ("PAUSE");
21
    return(0);
22
}

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.

von Karl H. (kbuchegg)


Lesenswert?

Mark Brandis schrieb:
> Zum Beispiel so:

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

tuts auch.

von Mark B. (markbrandis)


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

von Karl H. (kbuchegg)


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:
1
   char inLine[30];
2
3
   do {
4
     printf("Geben Sie einen Wert fuer U in Volt ein: ");
5
     fgets( inLine, sizeof( inLine ), stdin );
6
   } while( sscanf( inLine, "%d", &U) != 1 );

von Timea K. (elektroatoemli7)


Lesenswert?

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

:-)

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.