Forum: PC-Programmierung Überprüfung Tastatureingabe Gleitkommazahlen


von C++anfänger (Gast)


Lesenswert?

Hallo!

ich möchte mit c++  unter Linux ein kleines Konsolenprogramm schreiben. 
In der Konsole kann man die Werte von Variable von typ double entwender 
ändern
oder mit Enter -taste soll die Variable die alte Werte behalten.Für den 
Fall, dass statt einer Zahl irgendwas falsches z.B.: Buchstaben 
eingegeben werden, soll ne Fehlermeldung mit erneuter eingabe folgen.
um Enter taste  zu emfangen habe ich ncurses Library verwendet aber 
leider
konnte es  nicht zum laufen kriegen , hier ist mein code:
1
double b =10.07;
2
3
cout<<"b="<<b<<endl;
4
 
5
  do{
6
    cout<< "Bitte geben Sie ein:"<<endl;
7
    cout<< "Taste a: ändern"<<endl;
8
    cout<< "Tase  Enter : alte Wert von b behalten "<<endl;
9
    int  wahl=getch();
10
   
11
    switch(wahl){
12
     
13
    case 48:
14
      do{
15
      cout<<"Wert für b eingeben:"<<endl;
16
        if(!(cin >> b)){
17
      cout<<"Falche Eingabe! Zahl neu eingeben:"<<b<<endl;
18
       }
19
       }while(!b);
20
      break;
21
     
22
    case KEY_ENTER :      
23
      b=b;  
24
      cout<<"b="<<b<<endl;
25
      break;
26
     
27
    default : cout<< "falche Eingabe"<<endl;
28
    }  
29
  }while((wahl ==48)||(wahl==KEY_ENTER)); 
30
31
 cout<<"b="<<b<<endl;

kann mir da jemand weiterhelfen.

Beste danke

Lux

von Karl H. (kbuchegg)


Lesenswert?

Der Trick bei solchen Sachen besteht darin, dass man erst mal keine Zahl 
vom Benutzer einlesen lässt, sondern einen String.
Erst wenn der String die Tests besteht (oder ein Leerstring ist, in dem 
Fall übernimmt man dann den vorhergehenden Wert), wird dann aus diesem 
String die eigentliche Zahl erzeugt.

von C++anfänger (Gast)


Lesenswert?

habe ich gerade im Internert  recherchiert und  habe auf Tipps wie deine 
Idde gestoßen und habe folgnedes versucht:
1
double b =10.07;
2
char wert;
3
4
cout<<"b="<<b<<endl;
5
 
6
  do{
7
    cout<< "Bitte geben Sie ein:"<<endl;
8
    cout<< "Taste a: ändern"<<endl;
9
    cout<< "Tase  Enter : alte Wert von b behalten "<<endl;
10
    int  wahl=getch();
11
   
12
    switch(wahl){
13
     
14
    case 48:
15
      do{
16
      cout<<"Wert für b eingeben:"<<endl;
17
          cin >> wert;
18
        if(atoi(&wert) == 0{
19
      cout<<"Falche Eingabe! Zahl neu eingeben:"<<b<<endl;
20
       }
21
        b=wert;
22
       }while(!b);
23
      break;
24
     
25
    case KEY_ENTER :      
26
      b=b;  
27
      cout<<"b="<<b<<endl;
28
      break;
29
     
30
    default : cout<< "falche Eingabe"<<endl;
31
    }  
32
  }while((wahl ==48)||(wahl==KEY_ENTER)); 
33
34
 cout<<"b="<<b<<endl;
35
36
meine probleme,dass ich  jetzt  Enter taster nicht abfangen kann und auch atoi() eigentlich nur für int zahlen geeignet.

von Karl H. (kbuchegg)


Lesenswert?

C++anfänger schrieb:

> meine probleme,dass ich  jetzt  Enter taster nicht abfangen kann

die brauchst du auch gar nicht abfangen. Lies als String ein! Eine 
Stringeingabe kann auch leer sein


  std::string input;

  cin >> input;

> und
> auch atoi() eigentlich nur für int zahlen geeignet.

es gibt auch ein atof

von Klaus W. (mfgkw)


Lesenswert?

Um einen String zu testen, kann man vorteilhaft strtod() verwenden.
Dabei kann man einen Zeiger auf einen char* übergeben.
In dem char* wird nach dem Aufruf ein Zeiger auf das Zeichen liegen, bei 
dem die Konvertierung abgebrochen wurde.
Wenn das nicht das Stringende bzw. \n ist, steht hinter der 
konvertierten Zahl noch Müll.
Diesen Test kann man mit atof() nicht machen.

von C++anfänger (Gast)


Lesenswert?

habe versucht dein Vorschlag zu verfolgen,und habe folgends versucht
1
double b =10.07;
2
double bz;
3
std::string input;
4
5
cout<<"b="<<b<<endl;
6
  do{
7
    cout<< "Bitte geben Sie eine new Wert für b oder Tase  Enter :wenn die alte Wert von b behalten  wird"<<endl;
8
  std::cin >> input;
9
    
10
        if(alof(input) == 0){
11
      cout<<"Falche Eingabe! Zahl neu eingeben:"<<b<<endl;
12
       }
13
        bz=alof(input);
14
 }while(!bz);
15
16
if(bz==0)
17
{
18
   b=b;
19
}
20
else
21
{
22
 b=bz;
23
}
24
cout<< "b="<<endl;
aber es lauft  immer noch nicht

von Karl H. (kbuchegg)


Lesenswert?

alof ?

Was macht alof?

Und nein, atof kann dir bei der Erkennung ungültiger Zeichen nicht 
helfen. Im schlimmsten Fall konvertiert atof gar nichts und liefert 0 
zurück. Aber: atof liefert auch dann 0 zurück, wenn der String "0.0" war 
und das ist dann ja zweifellos richtig. In einem weiteren Fall liefert 
dir atof bei einem String von "3.56u87" dann eben 3.56 zurück. atof tut 
was es kann und bricht dann einfach kommentarlos ab. Aus dem 
Rückgabewert kann man nicht erschliessen, ob der String ausschliesslich 
aus einer gültigen 'Zahl' bestanden hat.

Entweder du benutzt strtod oder aber du schreibst dir eine Funktion, die 
im String nachsieht, ob nur zulässige Zeichen benutzt wurden.

von Karl H. (kbuchegg)


Lesenswert?

if(bz==0)
{
   b=b;
}
else
{
 b=bz;
}


machs doch nicht so kompliziert.

Wenn der String, denn dir der Benutzer gegeben hat leer ist (oder 
einfach nur ein \n enthält) dann kannst du dir die ganze Konvertiererei 
sparen.

von Karl H. (kbuchegg)


Lesenswert?

1
#include <iostream>
2
#include <string>
3
4
using namespace std;
5
6
7
int _main()
8
{
9
  double b = 10.07;
10
  std::string input;
11
12
  cout << "b=" << b << endl;
13
14
  bool isNumber = false;
15
16
  do {
17
    cout << "Bitte geben Sie eine new Wert für b oder Tase  Enter :wenn die alte Wert von b behalten  wird"<<endl;
18
    getline( cin, input );
19
    
20
    if( input.empty() )
21
      break;
22
23
    isNumber = true;
24
    for( size_t i = 0; i < input.length(); ++i ) {
25
      if( !( isdigit( input[i] ) || input[i] == '.' ) )
26
        isNumber = false;
27
    }
28
    
29
    if( isNumber )
30
      b = atof( input.data() );
31
  } while( !isNumber );
32
33
  cout << "b=" << b << endl;
34
}

und besorg dir ein C++ Buch.
Da wartet noch vieles auf dich, was man nicht durch Versuch und Irrtum 
lernen kann.


(Klaus: Ich habs jetzt absichtlich mit atof gemacht um ihn nicht mit 
strtod noch mehr zu verwirren)

von C++anfänger (Gast)


Lesenswert?

Vielen Danke.
Kannst du  mir  ein c++ Buch empfehlen. ich  habe  jetzt  ein buch  c++ 
Von A bis Z  von Jürgen Wolf von Bib ausgeliehen.

von C++anfänger (Gast)


Lesenswert?

noch ein kleines , wie kann es aber zB.  pi =3,14234, die als Macro in 
Headerdatei definert habe wenn ich die  eingebe, seine werte lesen kann.

von Karl H. (kbuchegg)


Lesenswert?

C++anfänger schrieb:
> noch ein kleines , wie kann es aber zB.  pi =3,14234, die als Macro in
> Headerdatei definert habe wenn ich die  eingebe, seine werte lesen kann.

Ähm. Was wird das jetzt? Lös ich da gerade deine Hausaufgaben?

Du hast einen Text, dieser Text kann natürlich "pi" sein, wenn ihn der 
Benutzer so eingibt. Und wenn er das ist, dann weißt du deine Konstante 
zu.

  if( input == "pi" )
    b = pi;

(Das ist noch nicht alles. Aber eigentlich sollst ja du deine Aufgaben 
lösen und nicht ich)

von Klaus W. (mfgkw)


Lesenswert?

C++anfänger schrieb:
> noch ein kleines , wie kann es aber zB.  pi =3,14234, die als Macro in
> Headerdatei definert habe wenn ich die  eingebe, seine werte lesen kann.

Sorry, davon verstehe ich kein Wort.
Aber in C schreibt man kein Komma, sondern einen Punkt in 
Gleitkommazahlen, falls das wichtig sein sollte.

von Klaus W. (mfgkw)


Lesenswert?

Karl Heinz Buchegger schrieb:
> (Klaus: Ich habs jetzt absichtlich mit atof gemacht um ihn nicht mit
> strtod noch mehr zu verwirren)

Ist schon recht.

Für strtod() braucht man ein char**; ich ahne Böses...

von Karl H. (kbuchegg)


Lesenswert?

Klaus Wachtler schrieb:
> Karl Heinz Buchegger schrieb:
>> (Klaus: Ich habs jetzt absichtlich mit atof gemacht um ihn nicht mit
>> strtod noch mehr zu verwirren)
>
> Ist schon recht.
>
> Für strtod() braucht man ein char**; ich ahne Böses...

Yep, das könnte im Zusammenhang mit std::string enormen Erklärungsbedarf 
geben. Eine andere Alternative wären noch String Streams gewesen, aber 
auch da wieder: Alles noch zu kompliziert für ihn.

von a no nym (Gast)


Lesenswert?

Karl Heinz Buchegger schrieb:
>   if( input == "pi" )

Geht das in C++ (Betonung auf ++) so einfach?

von Klaus W. (mfgkw)


Lesenswert?

Ja, wenn input ein std::string ist.

(In C mit einem nullterminierten String geht es ebenso einfach; die 
Frage ist dort nur ob man das gewünschte Ergebnis erhält. :-)

von Tip (Gast)


Lesenswert?

C++anfänger schrieb:
> pi =3,14234

Hast du pi neu definiert? Und mit "," wird das sowieso nichts.

von Klaus W. (mfgkw)


Lesenswert?

ach komm, 3 ist doch eine gute Näherung!

von a no nym (Gast)


Lesenswert?

Klaus Wachtler schrieb:
> Ja, wenn input ein std::string ist.
Sieh an, sehr praktisch. Danke.

> (In C mit einem nullterminierten String geht es ebenso einfach; die
> Frage ist dort nur ob man das gewünschte Ergebnis erhält. :-)
Sehr lustig...

von Klaus W. (mfgkw)


Lesenswert?

a no nym schrieb:
> Sehr lustig...

Finde ich wirklich lustig.

Das hier:
1
  const char *p = "Hallo";
2
3
  if( p=="Hallo" )
4
  {
5
    puts( "ja" );
6
  }
liefert z.B. mit dem Visual C++ keine Ausgabe, wenn man es ohne weitere 
Optionen kompiliert.
Mit /ZF oder /O1 dagegen gibt es "ja" aus.
Das ist also ein Kandidat für falsche Programme, die sogar mal 
funktionieren können, bei anderer Windrichtung oder Mondstellung dann 
nicht mehr.

Der gcc gibt zumindest eine Warnung aus, und dann auch "ja".

Daß so ein PRogramm vollkommener Blödsinn ist, sei sicherheitshalber 
nochmal erwähnt.

von Karl H. (kbuchegg)


Lesenswert?

a no nym schrieb:
> Klaus Wachtler schrieb:
>> Ja, wenn input ein std::string ist.
> Sieh an, sehr praktisch. Danke.

Wenn du das schon praktisch findest, dann sagt mir das, dass du ganz 
dringend ein C++ Buch brauchst. Du lässt ja >90% dessen, was dir C++ 
bietet einfach aus Unwissenheit links liegen! Dabei sind das dann genau 
die Dinge, die dir das Leben leicht machen und deren Nichtbenutzung dann 
zu Aussagen wie "C++ ist so kompliziert, ich komm mit Memory Management 
überhaupt nicht klar" führen.

C++ kann in einigen Bereich schon ein wenig kompliziert sein, 
unbestritten. Aber oft ist es nur deswegen kompliziert, weil die Leute 
gar nicht wissen, was sie schon alles vorgefertigt bei der Hand haben 
und wie man diese vorgefertigten Dinge einsetzt.

von a no nym (Gast)


Lesenswert?

Karl Heinz Buchegger schrieb:
> a no nym schrieb:
>> Klaus Wachtler schrieb:
>>> Ja, wenn input ein std::string ist.
>> Sieh an, sehr praktisch. Danke.
>
> Wenn du das schon praktisch findest, dann sagt mir das, dass du ganz
> dringend ein C++ Buch brauchst. Du lässt ja >90% dessen, was dir C++
> bietet einfach aus Unwissenheit links liegen!
Es sind exakt 100%, ich programmiere nur C. ;-)

von Karl H. (kbuchegg)


Lesenswert?

a no nym schrieb:

>> Wenn du das schon praktisch findest, dann sagt mir das, dass du ganz
>> dringend ein C++ Buch brauchst. Du lässt ja >90% dessen, was dir C++
>> bietet einfach aus Unwissenheit links liegen!
> Es sind exakt 100%, ich programmiere nur C. ;-)

Das erklärts natürlich :-)

Hast du vor, irgendwann mal den Umstieg zu machen?
In C++ gibt es vieles, was dir das Leben als C Programmierer extrem 
vereinfacht. Vor allen Dingen alles was mit dynamischer 
Speicherallokierung zu tun hat, kann man in C++ so abstrahieren, dass es 
seinen 'Schrecken' und seine Fehleranfälligkeit verliert. Und zwar ohne 
dass man einen Garbage Collector auch nur ansatzweise vermisst.

Der Umstieg, bis man sich in die OOP Welt eingelebt hat, dauert seine 
Zeit, aber auch in der Zeit bis dort hin kann man von C++ schon einiges 
profitieren.

UNd glaub nicht an den Mythos, dass C++ Programme aufgebläht seien. C++ 
Programme sind auch nicht aufgeblähter als gleichwertige(*) C Programme. 
Es kommt gar nicht so selten vor, dass die C++ Version sogar kleiner und 
schneller ist, weil der Compiler besser optimieren kann. Das sie dann 
auch oft noch schneller entwickelt werden kann, bei gleichzeitig 
besserer Fehlerfreiheit setzt dem ganzen noch die Krone auf


(*) Das "gleichwertig" ist wichtig. Denn oft werden hier Äpfel-Birnen 
Vergleiche gemacht, in dem zb im C-Programm das Fehlerhandling komplett 
ignoriert wird, das man aber in C++ durch die Verwendung der STL schon 
fast gratis mit dazubekommt. Überleg dir einfach, was du zb in C alles 
an Klimmzügen machen müsstest, bis du einen Ersatz für 
getline/std::string hast, der eine nahezu beliebig lange Eingabezeile 
einlesen und speichern kannst.

   char inputLine[80];
   fgets( inputLine, sizeof( InputLine ), stdin );

ist kein gleichwertiger Ersatz für

   std::string inputLine;
   getline( cin, inputLine );

da liegen Welten dazwischen.

von a no nym (Gast)


Lesenswert?

Karl Heinz Buchegger schrieb:
> a no nym schrieb:
>
>>> Wenn du das schon praktisch findest, dann sagt mir das, dass du ganz
>>> dringend ein C++ Buch brauchst. Du lässt ja >90% dessen, was dir C++
>>> bietet einfach aus Unwissenheit links liegen!
>> Es sind exakt 100%, ich programmiere nur C. ;-)
>
> Das erklärts natürlich :-)
>
> Hast du vor, irgendwann mal den Umstieg zu machen?

Da "irgendwann" recht allgemein ist kann ich die Frage guten Gewissens 
mit "ja" beantworten. :-)

Ne ernsthaft, ich will erstmal deutlich mehr Erfahrungen mit C sammeln, 
wenn ich genug Praxis habe (in ein paar Jahren) denke ich vielleicht mal 
über einen Wechsel nach.

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.