PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : c++: Äquivalent zu isNumeric?


Mosher
2008-12-29, 19:50:10
Hi.

Bin ein ziemlicher N00b, was Programmiersprachen angeht und bin gerade dabei, ein paar alte Sachen, die wir mal in der Schule unter Access programmiert haben, auf C++ zu schreiben.

Dabei vermisse ich schmerzlich die If IsNumeric(...) Abfrage aus Basic,
denn ich will folgendes realisieren (//-Kommentare beachten):
#include<iostream>
#include<cstdlib>
#include<math.h>


using namespace std;


double null1(double a, double b, double c);
double null2(double a, double b, double c);

int main()
{
double a, b, c, x1, x2;
int K;
K=1;
while(K==1)
{
cout << "Berechnet werden die Nullstellen der Fuktion ax^2 + bx + c \n";
cout << "a angeben: ";
cin >> a; //Hier soll so etwas kommen, wie "if not isNumeric(a) then msgbox "gib ne zahl ein""
cout << "b angeben: ";
cin >> b; //wie oben
cout << "c angeben: ";
cin >> c; // wie oben
x1 = null1(a,b,c);
x2 = null2(a,b,c);
if (b*b < 4*(a*c))
cout << "Keine Nullstellen im Definitionsbereich! \n";
else if (b*b == 4*(a*c))
cout << "Doppelte Nullstelle / Scheitel bei x1= "<< x1 << "\n";
else
{
cout << "x1: " << x1 << "\n";
cout << "x2: " << x2 << "\n";
}

cout << "Neue Berechnung durchfuehren? (1=ja, 2=nein): ";
cin >> K; // hier soll ebenfalls eine Probe auf gültige numerische Eingabe erfolgen, da das Programm bei Eingabe eines Buchstaben in einer Schleife hängenbleibt
while(K!=2&&K!=1)
{

cout << "Ungueltige Eingabe! (Du Penner)! \n";
cout << "Neue Berechnung durchfuehren? (1=ja, 2=nein): ";
cin >> K;

}
if(K==2)
cout << "Programm wird beendet... \n";


}
return 0;

}

double null1(double a, double b, double c)
{
double x1;
x1 = ((1/(2*a))*(-b+sqrt(b*b-4*a*c)));
return(x1);
}

double null2(double a, double b, double c)
{
double x2;
x2 = ((1/(2*a))*(-b-sqrt(b*b-4*a*c)));
return(x2);
}


kann mir da jmd. weiterhelfen?

mfg
Mosher

rotalever
2008-12-29, 20:48:15
Musst du dir wohl selber programmieren. Entweder nimmst du da eine Bibliothek, die dir regular expressions bereitstellt, oder du prüfst einfach den string durch, ob er z.B. nur 0-9 enthält.

Pinoccio
2008-12-29, 20:53:52
oder du prüfst einfach den string durch, ob er z.B. nur 0-9 enthält.http://www.cppreference.com/wiki/c/string/isdigit

mfg

rotalever
2008-12-29, 20:57:12
http://www.cppreference.com/wiki/c/string/isdigit

mfg
Verlangt aber einen Integer.

Mosher
2008-12-29, 20:59:57
Ich danke dir erstmal für die Hilfe, aber wie gesagt, ich bin ein ziemlicher N00b und kann jetzt nicht soviel mit deiner Antwort anfangen, da ich weder genau weiß, was ein String ist, noch, wie ich diesen auf einzelne Ziffern/Buchstaben hin überprüfe.
Das mit der Bibliothek leuchtet mir schon eher ein, werde mich da mal bissl umsehen.

Mir kam gerade die Idee, eine Variable als ein Unicodeelement zu deklarieren und nur solche Eingaben zuzulassen, die die Ziffern 0-9 im Unicode (Sprich 48 - 57) repräsentieren.

1. Frage: ist das möglich?

2. Frage: Wie überprüfe ich bei einer mehrstelligen Eingabe (zB 123BBB456) jede einzelne "Ziffer" auf einen bestimmten Wert?

Mosher
2008-12-29, 21:03:05
ups, hätte mal F5 drücken sollen ^^

dankeschön!! Denke, so kommích weiter

Mosher
2008-12-29, 21:05:16
Verlangt aber einen Integer.

Mist, doch net :(

muss ich doch wieder meine 2 Fragen ein paar Posts drüber stellen

rotalever
2008-12-29, 21:15:50
Also erst einmal hast du K als "int" deklariert, das heißt in K werden immer Integer = Ganzzahlen gespeichert und nichts anderes.

Wäre K ein String = Zeichenkette, so würde K nicht eine Zahl speichern sondern eine Kette von Zeichen, zum Beispiel das Wort test: K = "test"; Eine Zeichenkette könnte natürlich auch wie eine Zahl aussehen K = "123" aber das ist nicht dasselbe wie 123! Wenn man eine Zeichenkette hat, kann man mit einer Schleife über die Zeichen dieser Kette iterieren und jedes einzelne Zeichen prüfen ob es eine Ziffer ist. Ein Zeichen z müsste dann die Bedingung '0' <= z <= '9' erfüllen.

Trap
2008-12-29, 21:36:31
int x;
if(cin>>x) {
// Eingabe war zahl (zumindest der Anfang der Eingabe)
} else {
// Eingabe war keine zahl
}

Direkt mit cin zu Arbeiten find ich nicht so toll (dauernd Eingabepuffer und Zustand rücksetzen), ich nehm meistens getline(cin,string) und dann einen istringstream.

Mosher
2008-12-29, 21:37:19
Ok, ich könnte also K als char deklarieren

char K;

und dann prüfen ob jedes Zeichen des Strings z, der in K gespeichert wird, zwischen 48 und 57 liegt?

SO ungefähr hatte ich das geplant, ich konnte nur leider bisher nicht herausfinden, wie man bei einem String jedes einzelne Zeichen auf einen besmmten Wert hin überprüft. Kann mir da wer helfen?

Wenn dann die Eingabe insgesamt gültig ist, muss ich sie ja nurnoch wieder als float "callen" und damit weiterrechnen lassen, oder?


char K;
jemand gibt 123 ein, was bei der überprüfung des Strings für z 49, 50 und 51 ergeben sollte, erfüllt alles die Bedingung 48<= z <= 57, also lass ichs zu nem float umwandeln: 123.0 und gut is.

fehlt mir nurnoch der Code zum Überprüfen jeder einzelnen Stelle eines Strings ^^

Pinoccio
2008-12-29, 21:48:07
Verlangt aber einen Integer.Hm. :-(

Wie wäre es mit atof (http://www.cplusplus.com/reference/clibrary/cstdlib/atof.html) (bzw. auf deutsch (http://www.xon.de/x1/x1ref/index.html?html_atof.htm))?

Oder mit der STL und
#include <string>
#include <sstream>
std::stringstream sstr(myString);
int Zahl;
sstr >> Zahl;

mfg

Mosher
2008-12-29, 22:04:28
hmm, weiß jetz leider net, was STL ist.

Ich werds jetzt mal sau umständlich mit ´nem Array machen und mir da was zusammenbasteln. Geht mir ja erstmal darum, an eigenen Projekten die Sprache und ihre Möglichkeiten verstehen zu können.

Also vielen Dank für die Tipps!
mfg
Mosher

edit: Das Englische atof- Beispiel hat mir nen Lichtblitz beschert! Steht genau drin, was ich haben wollte, thx!!

rotalever
2008-12-29, 22:08:35
Also char z; ist nur ein einzelner Character/Zeichen. Eine Zeichenkette wäre zum Beispiel char * s; bzw. char s[n] mit n-1 als Anzahl der Zeichen in der Zeichenkette (eine Zeichenkette endet immer mit dem Zeichen '\0').
Somit ist eine Zeichenkette nichts anderes als ein Array von Zeichen über das man ganz einfach iterieren kann, also:

int i = 0;
char * s = "test"; // erzeugt test\0
while (s[i] != '\0')
{
//irgendwas überprüfen etc.
i++;
}

Mosher
2008-12-29, 22:34:47
aaah verstehe.

und statt char *s den wert "test" zuzuweisen, was test/0 ergeben würde,

könnte ich auch sagen

cin >> *s, was bei eingabe von "Zahl1" Zahl1/0 ergeben würde? und mit der whileschleife kann ich dann jedes Zeichen überprüfen bis zum Zeichen /0, was ja automatisch das letzte ist?

Sorry, wenn es so aussieht, als würde ich meine Fragen selbst beantworten, aber sowas hilft mir dabei, das Ganze etwas zu verinnerlichen.

werd´s gleich mal ausprobieren

mfg

Mosher
2008-12-29, 22:48:11
hmm..

also mit

char * s= "test"; funktioniert das,was ich vorhatte wunderbar.

nur mag es mir nicht gelingen char *s einen per Hand eingegebenen Wert zuzuweisen, nach dem Motto:
cin >> k;
char *s = k;

wenn mir noch jemand sagen könnte, wie man das realisieren könnte, wäre ich überglücklich für heute und nerv net weiter ^^

mfg

rotalever
2008-12-29, 23:05:40
Das Problem ist, dass du für ein Array in C++, also auch für char *, was ja ein Array ist, vorher den Speicher reservieren musst. Das geht natürlich bei Benutzereingaben nicht, da die beliebig lang sein können. Deshalb nimmt man hier besser den Datentyp "string", der wird automatisch verwaltet.
Du erstellst also am Besten eine Variable s vom Typ string. Die kannst du dann mit Hilfe von s.c_str() in ein const char * Array umwandeln.

Hier mal als funktionierendes Beispiel:


#include <iostream>
#include <string>

using namespace std;

int main()
{
string k;
cout << "Gib was ein: ";
cin >> k;
cout << "Die Eingabe war: " << k << "\n";

const char * k2 = k.c_str();
int i = 0;
bool zahl = true;
while (k2[i] != '\0')
{
if (k2[i] > '9' || k2[i] < '0')
{
zahl = false;
break;
}
i++;
}

if (zahl)
{
cout << "Eingabe war eine Zahl\n";
}
else
{
cout << "Eingabe war KEINE Zahl\n";

}


return 0;
}

DOOM
2008-12-29, 23:07:26
Mit "char *s = k;" weist du ja einen Zeichenkette (s) ein einzelnes Zeichen (k) zu!

Wenn dann musst du die Zeichen einzeln reinschreiben:
char *s = "";
// ...
s[0] = k;
// ...

ggf. den Index (hier "0") mit nem Wert iterieren.


Bezüglich der Speicherreservierung ist diese Lösung natürlich crap, also mit strings machen wie im Post vor mir erwähnt!

Abraxus
2008-12-29, 23:16:51
Wenn die Informatiker nicht immer das Rad neu erfinden würden, währen wir schon auf dem Mars.
http://www.cplusplus.com/reference/clibrary/cstdlib/strtod.html
http://www.cplusplus.com/reference/clibrary/cstdlib/atof.html

Mosher
2008-12-29, 23:20:19
Hab jetzt meine endgültige Lösung:


#include<iostream>
#include<cstdlib>
#include<math.h>

using namespace std;
const int MAX=5;

int main()
{
int i = 0;
double wert = 0;
char input[MAX];

cin.getline(input, MAX);

while(input[i] != '\0')
{
if(input[i] >= 48 &&input[i] <= 57)
{
cout << "passt!";
}
else
cout << "passt net!";
i++;

}
return 0;
}


wegen MAX2 beschränkt sich der zu überprüfende Bereich eh nur auf das 4 eingebene Zeichen und nur bei den Zeichen '0' - '9' wird ein passt ausgegeben. (is natürlich nur die Testfassung) Damit kann ich Leute, die mein tolles Nullstellenprogramm dazu missbrauchen wollen, Worte wie "Glied" oder "Popo" statt vernünftiger Werte für die Nullstellenberechnung heranzuziehen, zwingen, eine Zahl einzugeben.

also vielen Dank an alle für die Hilfe!

guten Rutsch
mfg

rotalever
2008-12-29, 23:30:22
Wenn die Informatiker nicht immer das Rad neu erfinden würden, währen wir schon auf dem Mars.
http://www.cplusplus.com/reference/clibrary/cstdlib/strtod.html
http://www.cplusplus.com/reference/clibrary/cstdlib/atof.html
??

ScottManDeath
2008-12-30, 00:06:11
http://www.boost.org/doc/libs/1_37_0/libs/conversion/lexical_cast.htm#examples

Alles andere ist Blasphemie ;)

Mosher
2008-12-30, 00:20:27
Nur wen´s interessiert:

Klappt soweit, nur einen Schwachpunkt hat die Lösung noch (auch deine, rotalever), die Zeichen '-' und '+' sind auch gültig. muss man noch irgendwie mit reinbasteln ^^

mfg, bis denne

Mosher
2008-12-30, 00:39:17
Aach Ka**e

nur noch ein Schönheitsfehler:
const int MAX=5;

char a[MAX];

cin.getline(a, MAX);

wieso läuft das komplette Programm durch, wenn jemand eine Eingabe mit mehr als 4 Zeichen macht? Array-Speicher überladen?
Noch Zeichen in irgendeinem Cin-Puffer?

Helft mir bitte nochma

rotalever
2008-12-30, 17:51:50
nur noch ein Schönheitsfehler:
const int MAX=5;

char a[MAX];

cin.getline(a, MAX);

wieso läuft das komplette Programm durch, wenn jemand eine Eingabe mit mehr als 4 Zeichen macht? Array-Speicher überladen?
Noch Zeichen in irgendeinem Cin-Puffer?
Meinst du damit, es stürzt ab? Jedenfalls denke ich, dass du char a[MAX+1] schreiben musst, da a nicht nur MAX Zeichen sondern auch noch das '\0' am Ende enthalten muss.

Mosher
2008-12-30, 18:55:38
ja,

1. MAX+1
2. cin.clear();
cin.ignore(cin.rdbuf()->in_avail());
musste jeweils unter cin.getline eingefügt werden.
dann ging´s ^^