Problem mit char-variable



  • Hallo,

    ich habe ein kleines Problem.

    Und zwar hab ich als Aufgabe bekommen einen Taschenrechner zu programmieren. Soweit so gut, das funktioniert auch alles. Der Benutzer muss abwechselnd eine Zahl und ein Rechenzeichen eingeben.

    Nun soll es allerdings möglich sein, dass der Taschenrechner das Ergebnis ausspuckt, wenn man statt einem Rechenzeichen den Befehl "Stop" eingibt.

    Wenn ich das so programmiere, haut mir das Programm allerdings ab und generiert in der Ausgabe eine Endlosschleife.

    Das komische ist aber, dass es funktioniert, wenn ich das ganze so programmiere, dass eine "0" beim Rechenzeichen das Ergebnis erzeugt.

    Woran liegt aber hier genau der Unterschied ?
    Das kann ich mir irgendwie nicht erklären.

    Und hat jmd eine Idee, wie es auch mit dem Stop-Befehl gehen könnte ?

    Wäre sehr dankbar !! 🙂

    --> Also in Zeile 24 erfolgt die Abfrage, ob der Benutzer eine "0" (bzw. ein "Stop" eingegeben hat.) Der Code, der danach folgt, sollte eigtl nicht entscheidend sein, aber der Vollständigkeit halber hab ich ihn mal beigefügt.

    #include <iostreams.h>
    
    // Die Funktion "ergebnis" summiert / subtrahiert / multipliziert / dividiert zwei Zahlen, je nachdem welches Rechenzeichen in der Variable "symbol" gespeichert wurde.
    float ergebnis(float x, float y, char symbol) {
            if (symbol=='+') {return x+y;}  
            if (symbol=='-') {return x-y;}
            if (symbol=='*') {return x*y;}
            if (symbol=='/') {return x/y;}  
    }
    
    //---------------------------------------------------------------------------
    #pragma argsused
    
    int main (int argc, char* argv[]) {
            char symbol[21];
            float a[20], summeplus=0, summeminus=0;
            int merke[20];
            int ende=1, j=1, zaehler=0, i=1;  // a: Zahl, b: Zwischenergebnis, i: Laufindex
            while (ende) {
                    cout << "Geben Sie die " << i << ". Zahl ein: ";
                    cin >> a[i];
                    cout << "Geben Sie das Rechenzeichen ein: ";
                    cin >> symbol[i];
                    if (symbol[i]=='0') {
                            for (int j=1; j<i; j++) {
                                    if (symbol[j]=='+' || symbol[j]=='-') {
                                            merke[j]=1;
                                            zaehler=0;
                                    }
                                    if (symbol[j]=='*' || symbol[j]=='/') {
                                            a[j+1] = ergebnis(a[j], a[j+1], symbol[j]);
                                            a[j-zaehler]=a[j+1];
                                            zaehler++;
                                    }
                            }
                            j=1;
                            while (j<i) {   
                                    if (merke[j]!=1) {
                                            a[j+1]=0;
                                    }
                                    if (symbol[j]=='+') {
                                            summeplus = summeplus + a[j+1];
                                    }
                                    if (symbol[j]=='-') {
                                            summeminus = summeminus + a[j+1];
                                    }
                                    j++;
                            }
                            cout << "Das Ergebnis lautet: " << summeplus+a[1]-summeminus;
                            cout << "\n";
                            cout << "\n";
                            cout << "Fuer neue Rechnung bitte 1 eingeben; mit 0 Programm beenden ";
                            cin >> ende;
                            i=0;
                    }
                    i++;
            }      
            return 0;
    }
    


  • Hi,

    das Problem ist folgendes:

    "Stop"
    

    ist eine Zeichenkette.
    Die bekommst du im Normalfall nicht in ein char hinein.

    aber zu deinem problem:
    ich habe mit zeichenketten und einzelnen zeichen die besten erfahrungen mit std::string gemacht.
    die klasse definiert alles was man zum leben braucht.
    Schau's dir einfach mal an: http://www.cplusplus.com/reference/string/string/



  • Okay vielen Dank, es klappt jetzt!!

    Jetzt hätte ich aber noch eine Frage.

    Ich will eine Fehlerabfrage einbauen, falls man statt einer Zahl z.B. einen Buchstaben eingibt. Dazu muss ich ja dann später die string-Variable in die double-Variable umwandeln.

    Aber wie mach ich das ? Mit dem Befehl str.begin(); bekomme ich leider die Fehlermeldung

    "Undefiniertes Symbol 'str'"

    Hat da jmd einen Tipp für mich ?



  • lukas88 schrieb:

    "Undefiniertes Symbol 'str'"

    Also wenn diese Fehlermeldung kommt, dann existiert str einfach nicht in dem Scope, wo du es verwenden willst. Kann es sein, dass du str irgendwo in einer Schleife deklarierst und es dann außerhalb dieser Schleife benutzen willst? In dem Fall (und davon gehe ich ganz stark aus) deklarier str einfach (mindestens) auf derselben Ebene, auf der du es später benutzen willst.

    Btw, nach Fließkomma umwandeln kannst du z.B. mit atof. Von deinem std::string müsstest du dann die Rückgabe der Methode c_str() übergeben. Die schicke C++-Variante wäre dann wohl per stringstream...



  • ok, noch eine sache:

    ich möchte die funktion

    FloatToStr
    

    verwenden, aber mir wird angezeigt, dass die Funktion undefiniert ist.

    Mit welchem #include-Befehl kann ich die einbinden ?



  • Ich glaube, das ist eine VCL-Funktion, die kannst du ohne VCL (C++ Builder Kram) halt nicht benutzen. Zum Umwandeln eines float-Wertes in einen String kannst du z.B. sprintf benutzen.

    float f=1.5;
    char s[64];
    sprintf(s,"%f",f);
    


  • _matze schrieb:

    Ich glaube, das ist eine VCL-Funktion, die kannst du ohne VCL (C++ Builder Kram) halt nicht benutzen. Zum Umwandeln eines float-Wertes in einen String kannst du z.B. sprintf benutzen.

    float f=1.5;
    char s[64];
    sprintf(s,"%f",f);
    

    ist sprintf nicht aus der c-lib?
    ich nehm für sowas immer die stringstream klassen aus <sstream>



  • daersc schrieb:

    ist sprintf nicht aus der c-lib?

    Ja ist es, und es funktioniert trotzdem! 😉

    Du kannst ja gerne stringstreams benutzen, mir gefällt sprintf halt besser. Ansichtsache...



  • _matze schrieb:

    Ich glaube, das ist eine VCL-Funktion, die kannst du ohne VCL (C++ Builder Kram) halt nicht benutzen. Zum Umwandeln eines float-Wertes in einen String kannst du z.B. sprintf benutzen.

    float f=1.5;
    char s[64];
    sprintf(s,"%f",f);
    

    Danke schonmal bis hierhin.

    Und wie kann ich dann den character in einen std::string umwandeln ?

    Mein Ziel ist nämlich die Eingabe des Benutzers im std:string-Format abzuspeichern. Dies soll dann in double konvertiert werden und double wiederum in std::string. Durch den Vergleich der beiden std::string-Variablen könnte ich dann feststellen, ob der Benutzer versehentlich eine "ungültige" Zahl, sprich einen Buchstaben oder so eingegeben hat.


  • Administrator

    http://www.c-plusplus.net/forum/viewtopic-var-t-is-39488.html

    @_matze,
    Aber in einem C++ Forum sollte man doch immerhin die C++ Lösung dazu setzen. Mindestens als Ergänzung, oder halt dann auf den FAQ Artikel verweisen 😉

    Grüssli



  • Nen paar Fehler waren ja noch drin - und bissl was war einfach unnötig...

    #include <iostreams> //<iostream.h> war noch NIE standard!
    
    float ergebnis(float x, float y, char symbol)
    {
    	float ergebnis = x;
    	switch (symbol) //eigtl nimmt man ab 2-3 versch. Werten switch - nicht nur, weils schneller ist, sondern auch, weils übersichtlicher ist ^^
    	{
    	case '+': ergebnis += y; break;
    	case '-': ergebnis -= y; break;
    	case '*': ergebnis *= y; break;
    	case '/': ergebnis /= y; break;
    	default:
    		//denk dir was aus ^^ kannst es auch leer lassen, aber ich würde ne exception werfen oder - falls du das (noch) nicht kennst, das default ganz weglassen
    	}
    	return ergebnis;
    } 
    
    using namespace std; //ansonsten müsstest du immer std::cin / std::cout / std::endl schreiben
    
    int main () //das zeugs brauchst du nicht ^^
    { //das hier sieht alles bissl sehr... umständlich aus - mir war es jz auch zu viel arbeit, alles durchzugucken - aber es gibt auch eine for-Schleife  ^^
            char symbol[21]; //nimm std::string oder zumindest std::vector<char> - kannst du beides so behandeln, wie dein array - aber brauchst keine Angst haben, dass es knallt, wenn ma mehr als 21Zeichen drin stehen...
            float a[20], summeplus=0, summeminus=0; //in C++ deklariert man die Variablen eigentlich immer erst dort, wo man sie auch braucht...
            int merke[20]; //... ansonsten hat man am anfang immer so nen hässlichen großen variablen-block und sieht nicht sofort, welche variable wozu gehört etc...
            int ende=1, j=1, zaehler=0, i=1;  // a: Zahl, b: Zwischenergebnis, i: Laufindex //i als laufindex wird eigtl _immer_ erst in der schleife an sich deklariert (und so bald man nen laufindex braucht, sollte man auch ne for-schleife nehmen ^^)
            while (ende) { 
                    cout << "Geben Sie die " << i << ". Zahl ein: "; 
                    cin >> a[i]; 
                    cout << "Geben Sie das Rechenzeichen ein: "; 
                    cin >> symbol[i]; 
                    if (symbol[i]=='0') { 
                            for (int j=1; j<i; j++) { 
                                    if (symbol[j]=='+' || symbol[j]=='-') { 
                                            merke[j]=1; 
                                            zaehler=0; 
                                    } 
                                    if (symbol[j]=='*' || symbol[j]=='/') { 
                                            a[j+1] = ergebnis(a[j], a[j+1], symbol[j]); 
                                            a[j-zaehler]=a[j+1]; 
                                            zaehler++; 
                                    } 
                            } 
                            j=1; 
                            while (j<i) {   
                                    if (merke[j]!=1) { 
                                            a[j+1]=0; 
                                    } 
                                    if (symbol[j]=='+') { 
                                            summeplus = summeplus + a[j+1]; 
                                    } 
                                    if (symbol[j]=='-') { 
                                            summeminus = summeminus + a[j+1]; 
                                    } 
                                    j++; 
                            } 
                            cout << "Das Ergebnis lautet: " << summeplus+a[1]-summeminus
    							<< '\n'
    							<< '\n'
    							<< "Fuer neue Rechnung bitte 1 eingeben; mit 0 Programm beenden ";
                            cin >> ende; 
                            i=0; 
                    } 
                    i++; 
            }       
            return 0; //das ist zwar unnötig, aber es mitzuschreiben ist auch nicht falsch
    }
    

    ich hoffe, ich hab dich nicht noch mehr verwirrt ^^

    bb

    PS:

    Du kannst ja gerne stringstreams benutzen, mir gefällt sprintf halt besser. Ansichtsache...

    Nein, es ist eben keine Ansichts-Sache - das hatten wir schon oft genug - es hat eben nur Nachteile und keinen einzigen Vorteil - bevor du das Ggnteil behauptest: Benutz die Forensuche...



  • Aegh, wenn man 1 Problem löst, kommen 2 neue...

    Also dank eurer Hilfen klappt das nun mit der Konvertierung.
    Dafür klappt das mit dem Vergleichen der beiden string-Formate nicht (weil C++ große Zahlen ja meits mit e darstellt. Also ist in diesen Fällen der Vergleich negativ, auch wenn es sich um die gleichen Zahlen handelt.)

    Hat denn irgendwer von euch eine andere Idee, wie man überprüfen kann, ob es sich bei einem string im logischen Sinn um eine Zahl handelt oder ob der String auch Buchstabeb bzw. Sonderzeichen enthält ?

    Wäre über jeden Tipp dankbar...



  • bin mir nicht ganz sicher aber es gibt doch im c-standard so funktionen wie atoi oder atof oder so...
    die erledigen meines wissens nach sowas, aber wie gesagt ich hab nicht wirklich viel ahnung von denen^^



  • @unskilled:

    Danke für deine allgemein Tipps. WErde das beherzigen und ändern. 🙂


  • Administrator

    @lukas88,
    Verwende bei der Umwandlung die Manipulatoren um die richtige Formatierung zu erreichen:
    http://www.cplusplus.com/reference/iostream/manipulators/

    Grüssli

    PS: Wieso wandelst du Zahlen in Strings um, damit du sie nachher vergleichen kannst? Wäre es nicht sinnvoller die Sache in der anderen Reihenfolge durchzuführen 🙂


Anmelden zum Antworten