Autor Thema: [C++] Abfragen, ob eine Floatzahl eingegeben wurde  (Gelesen 10982 mal)

Offline Zeh Emm

  • Lektor
  • kühlt mit Stickstoff
  • **
  • Beiträge: 3.008
  • Shake that ass, Bitch...
    • Meine private Seite - befindet sich aber im Aufbau
[C++] Abfragen, ob eine Floatzahl eingegeben wurde
« am: 21. Mai 2008, 23:09:42 »
Moinsen.

Wir sollen für die Uni ein Programm schreiben, welches das kgV und den ggT zweier Integerzahlen ermittelt.

Nun möchte ich aber nach der Eingabe einer Float-Zahl, dass abgebrochen wird. Das tut es nur bedingt.

Einerseits wird ausgegeben, dass die Zahl nicht im Definitionsbereich liegt, was auch richtig ist. Andererseits wird aber ein cout noch mit ausgegeben, was eigentlich nciht vorkommen sollte.

Hat einer eine Idee?

#include <stdio.h>
#include <iostream.h>

int ggt( int m, int n){
if (n == 0){
return m;
}
else{
return ggt(n,m%n);
}
return m;
}

int kgv(int m, int n){
return( m*n/ggt(m,n) );
}

int main(){
int n=0;
cout<<"Bitte geben Sie die erste Zahl >0 ein:\n";
cin>>n;
//hier müsste eine Abfrage rein, ob n ein int ist oder nicht ansonsten -->break
int m=0;
cout<<"Bitte geben Sie die zweite Zahl >0 ein:\n";
cin>>m;

if(m>0 && n >0){
cout<<"Das kgV lautet: "<<kgv(m,n)<<endl;
cout<<"Der ggT lautet: "<<ggt(m,n)<<endl;
}
else{
cout<<" Mindestens eine der Eingaben ist nicht aus dem natuerlichen Zahlenbereich\n";
}
return 0;
}
/

Die Ausgabe ist Folgende
Zitat
claas@claas-linux:~/Desktop/1$ ./ggt
Bitte geben Sie die erste Zahl >0 ein:
111.456
Bitte geben Sie die zweite Zahl >0 ein:<-- Soll nicht erscheinen
 Mindestens eine der Eingaben ist nicht aus dem natuerlichen Zahlenbereich
claas@claas-linux:~/Desktop/1$
« Letzte Änderung: 21. Mai 2008, 23:13:52 von Claas M »
"Hat sich durch das, was Du getan hast, Dein Leben verbessert?" - American History X
"Quot me nutrit me destruit"

"Your Mom is so dumb that she tried to minimize a 12 variable function to a minimal sum of products expression using a karnaugh map instead of the Quine-McCluskey"

<SenioR> whahahah fravec! Ich hab deine Mudda gebumst!!  <@Fravec> Papa, hau ab, ich rede hier mit Freunden...

Offline nemon

  • Administrator
  • kühlt mit Trockeneis
  • ******
  • Beiträge: 1.628
  • Da bin ich wieder
Re: [C++] Abfragen, ob eine Floatzahl eingegeben wurde
« Antwort #1 am: 21. Mai 2008, 23:16:57 »
als string einlesen und zeichen für zeichen vergleichen, ob es eine ziffer ist, wenn nicht, dann abbruch. wenn es passt, in einen integer wandeln. hab sowas mal als "sichere" methode in delphi geschrieben, mit allen prüfungen ca. 100 zeilen code

Offline Gargamel

  • hat ne Eismaschine
  • *****
  • Beiträge: 395
Re: [C++] Abfragen, ob eine Floatzahl eingegeben wurde
« Antwort #2 am: 21. Mai 2008, 23:25:37 »
int main(){
int n=0;
cout<<"Bitte geben Sie die erste Zahl >0 ein:\n";
cin>>n;
//hier müsste eine Abfrage rein, ob n ein int ist oder nicht ansonsten -->break
        if(n>0){
            int m=0;
            cout<<"Bitte geben Sie die zweite Zahl >0 ein:\n";
            cin>>m;

            if(m>0){
cout<<"Das kgV lautet: "<<kgv(m,n)<<endl;
cout<<"Der ggT lautet: "<<ggt(m,n)<<endl;
                return 0;
            }
        }
cout<<" Mindestens eine der Eingaben ist nicht aus dem natuerlichen Zahlenbereich\n";
return 1;
}
@Class: so?

Ich gehe jetzt einfach mal davon aus, dass das "cin>>n" die Überprüfung übernimmt, ob es sich bei der Eingabe um einen Integer handelt. Soo genau kenne ich mich nicht mit C++ aus. Ansonsten - siehe nemons Vorschlag. Das könnte man dann auch gleich noch mit Exceptions koppeln, um die Fehlerbehandlung eleganter abhandeln zu können. ;)

Offline nemon

  • Administrator
  • kühlt mit Trockeneis
  • ******
  • Beiträge: 1.628
  • Da bin ich wieder
Re: [C++] Abfragen, ob eine Floatzahl eingegeben wurde
« Antwort #3 am: 21. Mai 2008, 23:36:45 »
ich weiß nicht, wie c++ es handhabt, aber im prinzip werden ja bytes aus dem tastaturpuffer in die variable geschoben. wenn du nun "buchstaben", welche ja eigentlich ein byte sind, da reinschiebst, kannst du aus 4 buchstaben einen int32 zusammenbasteln, also wenn da kein fehlerabfang hintersteckt, kann ein cin>>n auch funktionieren, wenn cin ABCD beinhaltet, dann müsste n 1094861636 werden. damit würde dein programm weiterrechnen. zwar bin ich mir hierbei nicht sicher, da aber bekannt ist, dass in c++ fehlerabfangmäßig kaum etwas implementiert ist, halte ich es für gut möglich. sag doch mal 'a'>>n und lass dir n als integer formatiert ausgeben

Offline Zeh Emm

  • Lektor
  • kühlt mit Stickstoff
  • **
  • Beiträge: 3.008
  • Shake that ass, Bitch...
    • Meine private Seite - befindet sich aber im Aufbau
Re: [C++] Abfragen, ob eine Floatzahl eingegeben wurde
« Antwort #4 am: 22. Mai 2008, 06:57:29 »
@Gargamel: Danke aber der spuckt wie vorher aus, dass ich die zweite Zahl eingeben soll.
Mir kam aber gerade die Idee m und n als floats einzulesen und dann mal zu gucken, ob in der Zeichenkette ein . enthalten ist oder nciht. Wenn ja, dann soll abgebrochen werden ansonsten weitermachen.

Nur habe ich bei meiner Suche nur merkwürdige Snippets gefunden, mit denen ich nichts anfangen kann bzw Lösungen, die auf die Installation weiterer Bibliotheken zurückgreift und ich bin mir nciht sicher, ob ich am Unirechner Sachen installieren kann.

Hat einer von euch evtl ein kurzes Snippet, mit dem man sich das zurechtbasteln kann?
"Hat sich durch das, was Du getan hast, Dein Leben verbessert?" - American History X
"Quot me nutrit me destruit"

"Your Mom is so dumb that she tried to minimize a 12 variable function to a minimal sum of products expression using a karnaugh map instead of the Quine-McCluskey"

<SenioR> whahahah fravec! Ich hab deine Mudda gebumst!!  <@Fravec> Papa, hau ab, ich rede hier mit Freunden...

Offline nemon

  • Administrator
  • kühlt mit Trockeneis
  • ******
  • Beiträge: 1.628
  • Da bin ich wieder
Re: [C++] Abfragen, ob eine Floatzahl eingegeben wurde
« Antwort #5 am: 22. Mai 2008, 10:41:58 »
du kannst einen float nicht von vorne nach hinten durchgehen und ein "." suchen. in einem float wird ein komma nicht als komma gespeichert, es gibt einen bereich aus den vorderen bits mit ganzzahliger bedeutung und ein teil der hinteren bits, die die nachkommastellen ausdrücken.

und nein, ich poste hier keinen code, das musst du dir schon selber zurechtbasteln, ist ja auch keine allsu schwere aufgabenstellung.

Offline Gargamel

  • hat ne Eismaschine
  • *****
  • Beiträge: 395
Re: [C++] Abfragen, ob eine Floatzahl eingegeben wurde
« Antwort #6 am: 22. Mai 2008, 12:51:29 »
Ok, ich gebe zu, ich hab den Code gestern nicht getestet. Ich vermute mal, wenn man "2.75" eingibt, läuft das wie folgt ab:

Das Einlesen der ersten Zahl mit "cin>>n" liest die Zeichen '2' und '.' von der standard-Eingabe. Beim Zeichen '.' merkt der Parser, dass dieses Zeichen nicht zu einer natürlichen Zahl passt und beendet das einlesen. Das Zeichen '.' wird dann wahrscheinlich in den Eingabepuffer zurückgeschickt, mit einem einzelnen Zeichen ist das üblicherweise möglich. Die Variable "n" erhält also den Wert "2".
Nun wird das Einlesen der zweiten Zahl mit "cin>>m" gestartet. Im Eingabepuffer befinden sich aber noch die verbleibenden Zeichen, nämlich ".75". Was der Parser nun macht, wenn die Zeichenkette nicht mit einer Ziffer beginnt, weiß ich nicht. Vielleicht solltest du mal in ein Buch über C++ gucken, ob da das Verhalten von den Eingaberoutinen genauer erklärt ist. Also im Endeffekt suchst du den ">>" Operator aus der Klasse "std::istream" mit Rückgabetyp "int".

Edit: Tatsächlich suchst du die Beschreibung zu "istream& operator>> (int& val )". Ich hatte schon wieder vergessen, dass bei C++ ja alles mögliche über Referenzen gelöst wird. :nut: Heftige Sprache zum Einstieg in die Programmiererei...

BTW: Ich glaube statt
#include <stdio.h>
#include <iostream.h>
wäre folgendes besser:
#include <iostream>
using namespace std;
« Letzte Änderung: 22. Mai 2008, 13:03:07 von Gargamel »

Offline Zeh Emm

  • Lektor
  • kühlt mit Stickstoff
  • **
  • Beiträge: 3.008
  • Shake that ass, Bitch...
    • Meine private Seite - befindet sich aber im Aufbau
Re: [C++] Abfragen, ob eine Floatzahl eingegeben wurde
« Antwort #7 am: 22. Mai 2008, 13:35:26 »
Edit: Tatsächlich suchst du die Beschreibung zu "istream& operator>> (int& val )". Ich hatte schon wieder vergessen, dass bei C++ ja alles mögliche über Referenzen gelöst wird. :nut: Heftige Sprache zum Einstieg in die Programmiererei...

BTW: Ich glaube statt
#include <stdio.h>
#include <iostream.h>
wäre folgendes besser:
#include <iostream>
using namespace std;

Koennte dies erklaeren, warum mir der g++-Compiler unter Ubuntu eine warning ueber veraltete Header aussspuckt?

@nemon: Erinnert mich an Informatik1. :)
"Hat sich durch das, was Du getan hast, Dein Leben verbessert?" - American History X
"Quot me nutrit me destruit"

"Your Mom is so dumb that she tried to minimize a 12 variable function to a minimal sum of products expression using a karnaugh map instead of the Quine-McCluskey"

<SenioR> whahahah fravec! Ich hab deine Mudda gebumst!!  <@Fravec> Papa, hau ab, ich rede hier mit Freunden...

Offline Gargamel

  • hat ne Eismaschine
  • *****
  • Beiträge: 395
Re: [C++] Abfragen, ob eine Floatzahl eingegeben wurde
« Antwort #8 am: 22. Mai 2008, 13:44:55 »
Koennte dies erklaeren, warum mir der g++-Compiler unter Ubuntu eine warning ueber veraltete Header aussspuckt?
Jaaaa!

Und immer schön "g++ -Wall" benutzen...  :wink:

Offline Zeh Emm

  • Lektor
  • kühlt mit Stickstoff
  • **
  • Beiträge: 3.008
  • Shake that ass, Bitch...
    • Meine private Seite - befindet sich aber im Aufbau
Re: [C++] Abfragen, ob eine Floatzahl eingegeben wurde
« Antwort #9 am: 22. Mai 2008, 16:00:29 »
g++ Wall?

Aber ich hatte vorhin die ultimative Idee:
-Ich lese die Variable als float aus.
-ich generiere eine Hilfsvariable, die den auf int gecastete float hat.
-wenn float-var - Hilfsvar > 0 : Fehlerausgabe...

Leider erhalte ich hier momentan keinerlei Ausgabe, nicht einmal ein simples cout<< geht... komisch, komisch alles... nacher mal bei mir zuhause testen... wohooo....
"Hat sich durch das, was Du getan hast, Dein Leben verbessert?" - American History X
"Quot me nutrit me destruit"

"Your Mom is so dumb that she tried to minimize a 12 variable function to a minimal sum of products expression using a karnaugh map instead of the Quine-McCluskey"

<SenioR> whahahah fravec! Ich hab deine Mudda gebumst!!  <@Fravec> Papa, hau ab, ich rede hier mit Freunden...

Offline nemon

  • Administrator
  • kühlt mit Trockeneis
  • ******
  • Beiträge: 1.628
  • Da bin ich wieder
Re: [C++] Abfragen, ob eine Floatzahl eingegeben wurde
« Antwort #10 am: 22. Mai 2008, 17:18:43 »
nein, claas, auch beim einlesen als flaot hast du keinen fehlerabfang, möglicherweise funktioniert es so, wie gargamel es für integer beschrieben hat, nur, dass eben der punkt auch ein erlaubtes zeichen ist. ich würde, wie gesagt, es als string auslesen und zeichen für zeichen in einen 2. string kopieren, der dann nur noch ziffern enthält und dann in einen int wandeln. optional wär vor dem wandeln natürlich eine größenkontrolle möglich, aber das dürfte den umfang deiner übung etwas überschreiten.

Offline Gargamel

  • hat ne Eismaschine
  • *****
  • Beiträge: 395
Re: [C++] Abfragen, ob eine Floatzahl eingegeben wurde
« Antwort #11 am: 22. Mai 2008, 18:07:18 »
g++ Wall?
Nein, keine Mauer (Wall). Ich wollte dir vorschlagen, g++ mit der Option "-Wall" benutzen, um (nahezu) alle Warnungen zu aktivieren, die der Compiler erzeugen kann. Damit z.B. Warnungen erscheinen, wenn Variablen nicht benutzt werden. Oder wenn man statt einem Vergleichsoperator einen Zuweisungsoperator in einer if-Abfrage verwendet hat, wie bei "if (a = b)". Für Details siehe "man g++".

Also so z.B.:
g++ -Wall marsrobot.cc -o marsrobot



Offline Zeh Emm

  • Lektor
  • kühlt mit Stickstoff
  • **
  • Beiträge: 3.008
  • Shake that ass, Bitch...
    • Meine private Seite - befindet sich aber im Aufbau
Re: [C++] Abfragen, ob eine Floatzahl eingegeben wurde
« Antwort #12 am: 23. Mai 2008, 15:06:55 »
Aaaalso... gestern und heute ein turbulenter Tag aber ich habe Neuigkeiten.

Der Compiler an der Uni spuckte immer irgendwelche Warnings aus, die wir immer ignorierten, weil alles lief (irgendwas wurde durch eine andere Bib ersetzt oder irgend sowas in die Richtung) Naja, egal... Dann lief in einem neuen Programm nichteinmal ein simples

int main(){
cout<<"Ich bin der Ausgabetext\n";
return 0;
}

Dann lief nichteinmal der 1:1 kopierte Code, der vorher aber lief... Verrückt³... Ok, den Krempel gepackt, und mir per E-Mail gesendet und versucht dort zu kompilieren. Ich habe vermutlich eine neuere Compilerversion oder weiß der Geier, jedenfalls erhielt ich eine Warning, dass cout nicht definiert ist. Ok, dann habe ich den Header so angepasst, wie Gargamel es vorgeschlagen hatte und siehe da, ich erhalte meine gewünschte Ausgabe.

Als ich dies einer Komilitonin sagte meinte sie auch, dass sie die 'gleichen' Fehler hatte, und jedesmal std:: vor cout und cin hat schreiben müssen... passt auf jeden Fall zu meinem Headerproblem.

Naja langer Rede kurzer Sinn: Ich habe mein Problem annehmbar lösen können:
Da die Modulo-Operation leider nicht für floatzahlen geht kam mir ein cast in den Sinn. Ich lese die Zahl als float ein, und bilde die Different aus der Zahl und der gecasteten Zahl. Ist die Differenz größer als 0, wird abgebrochen.

Nun der komplette Quellcode:

#include <iostream>
using namespace std;

int ggt( int m, int n){
if (n == 0){
return m;
}
else{
ggt(n,m%n);
}
return m;
}

int kgv(int m, int n){
return( m*n/ggt(m,n) );
}

int main(){
float n=0.0;
float m=0.0;
cout<<"Bitte geben Sie eine natuerliche Zahl ein:\n";
cin>>n; //Einlesen von n
if(n-(int)n != 0){ //von n wird die gecastete Zahl n abgezogen
cout<<"Die eingegebene Zahl ist nicht aus dem natuerlichen Zahlenbereich\n"; //wenn die Differenz groesser als 0 wird abgebrochen
}
else{ //und ansonsten die zweite Zahl eingelesen
cout<<"Bitte geben Sie eine weitere natuerliche Zahl ein:\n";
cin>>m; //Einlesen von m
if(m-(int)m == 0){ //Selbiger Test wie fuer n, desmal aber auf m 
cout<<"Das kgV lautet: "<<kgv(m,n)<<endl; //Wenn Test erfolgreich ist, Ergebnisse ausgeben
cout<<"Der ggT lautet: "<<ggt(m,n)<<endl;
}
else{
cout<<"Die eingegebene Zahl ist nicht aus dem natuerlichen Zahlenbereich\n";//Ansonsten Fehlermeldung ausspucken
}
}
return 0;
}

Dummerweise erhalte ich bei der Eingabe eines Chars noch die Ausgabe, dass ich die zweite Zahl eingeben soll. Zwar wird abgebrochen aber es ist ein Schönheitsfehler. Weiß einer dafür einen Rat?
« Letzte Änderung: 23. Mai 2008, 16:01:12 von Claas M »
"Hat sich durch das, was Du getan hast, Dein Leben verbessert?" - American History X
"Quot me nutrit me destruit"

"Your Mom is so dumb that she tried to minimize a 12 variable function to a minimal sum of products expression using a karnaugh map instead of the Quine-McCluskey"

<SenioR> whahahah fravec! Ich hab deine Mudda gebumst!!  <@Fravec> Papa, hau ab, ich rede hier mit Freunden...

Offline Gargamel

  • hat ne Eismaschine
  • *****
  • Beiträge: 395
Re: [C++] Abfragen, ob eine Floatzahl eingegeben wurde
« Antwort #13 am: 23. Mai 2008, 17:35:42 »
Der Compiler an der Uni spuckte immer irgendwelche Warnings aus, die wir immer ignorierten, weil alles lief [...]
Tja... Dann hast du ja bestimmt dadurch gelernt, dass man Warnings immer beachten (und zumindenst zu verstehen versuchen) sollte. ;)
Zitat
Als ich dies einer Komilitonin sagte meinte sie auch, dass sie die 'gleichen' Fehler hatte, und jedesmal std:: vor cout und cin hat schreiben müssen... passt auf jeden Fall zu meinem Headerproblem.
Falls es in der Hinsicht noch Unklarheiten gibt, guck mal in ein C++ Buch zum Thema Namensräume (Schlüsselwort "namespace"). Zu dem Unterschied zwischen "#include <iostream.h>" und "#include <iostream>" steht iirc auch was im Stroustrup'schen Standardwerk "Die C++ Programmiersprache".

Zitat
[...]
Dummerweise erhalte ich bei der Eingabe eines Chars noch die Ausgabe, dass ich die zweite Zahl eingeben soll. Zwar wird abgebrochen aber es ist ein Schönheitsfehler. Weiß einer dafür einen Rat?
Guck dir in einem Buch an, wie das Verhalten der Eingaberoutinen definiert ist. Genau das selbe müsste ich tun, um es dir besser erklären zu können...

Um alle Eventualitäten abfangen zu können, wirst du es machen müssen, wie nemon schon schrieb. Zeilenweise Text als String einlesen und diesen String Zeichen für Zeichen abarbeiten um ihn in eine Zahl umzuwandeln bzw. um zu erkennen, ob die Eingabe keine Zahl ist.

Oder aber du liest Zeichen für Zeichen einzeln ein, damit dein Programm quasi sofort reagieren kann, wenn eine "verbotene" Taste gedrückt wurde. Dabei könnte es aber evtl. Probleme geben, falls der Standard-Eingabe Datenstrom nur gepuffert an das Programm übertragen wird.

Man könnte natürlich auch auf die Idee kommen, nachdem eine Zahl eingelesen wurde alle darauf folgenden Zeichen bis zum Zeilenende einzulesen und zu verwerfen. Aber das bringt ein Problem mit sich, wenn nach der Zahl garkeine Zeichen mehr folgen - dann wird die Leseroutine mit hoher Wahrscheinlichkeit blockieren...