upn taschenrechner (ascii problem)



  • Du prüfst einfach ab, ob es sich um einen Operator handelt (s. obige Abfragen) und wenn nicht, dann wandelst du den Wert erst in eine Zahl um. (Warum einfach, wenn's auch kompliziert geht?)



  • habs mal so versucht, da bekomm ich ein compilerfehler:
    http://666kb.com/i/atfnck2lzrq0ywc9x.jpg



  • Du verwendest eine Zuweisung statt eines Vergleichs ('=' statt '==').

    Aber das ist sowieso alles nicht optimal, denn in C++ programmiert man anders.



  • naja ich weiss. Bin aber auch erst am anfang meiner programmierkarriere, sprich, ich hab vor 6 wochen angefangen 😉

    thx anyway



  • man man. Habs geändert, aber er meckert immer noch:
    http://666kb.com/i/atfo49qr3tw5hvspx.jpg



  • andigr schrieb:

    naja ich weiss. Bin aber auch erst am anfang meiner programmierkarriere, sprich, ich hab vor 6 wochen angefangen 😉

    Jupp, man kann aber gleich „richtig“ anfangen. Das heißt insbesondere, dass man gleich die korrekten Datenstrukturen verwendet und keine Low-Level Pointer-Arrays oder C-Funktionen wie 'atoi'. Das ist fehleranfällig und erschwert nur alles.

    Folgender Code behebt diese Probleme (allerdings *nur* diese).

    #include <iostream>     // Für die cout und endl.
    #include <stack>        // Für stack.
    #include <string>       // Für string.
    #include <sstream>      // Für stringstream.
    #include <map>          // Für pair.
    #include <functional>   // Für for_each.
    #include <algorithm>    // Für bind_1st, mem_fun
    
    typedef std::pair<int, int> operators;
    
    // Extrahiert die obersten beiden Zahlen aus einem Stack
    // und gibt sie als Zahlenpaar zurück.
    operators get_ops(std::stack<int>& stack) {
        operators ret;
        ret.second = stack.top();
        stack.pop();
        ret.first = stack.top();
        stack.pop();
        return ret;
    }
    
    int main(int argc, char* argv[]) {
        std::stack<int> stack;
        std::stringstream input;
    
        // Schiebt die Kommandozeilenargumente in einen Stream,
        // aus dem wir im folgenden die Eingabe lesen.
        for (int i = 1; i < argc; ++i) {
            input << argv[i] << ' ';
        }
    
        std::string token;
        while (input >> token)  {
            if (token == "+") {
                operators ops = get_ops(stack);
                stack.push(ops.first + ops.second);
            }
            else if (token == "-") {
                operators ops = get_ops(stack);
                stack.push(ops.first - ops.second);
            }
            else if (token == "*") {
                operators ops = get_ops(stack);
                stack.push(ops.first * ops.second);
            }
            else if (token == "/") {
                operators ops = get_ops(stack);
                stack.push(ops.first / ops.second);
            }
            else {
                // Es wurde kein Rechenzeichen eingegeben, wir erwarten also
                // eine Zahl. Um diese zu lesen, müssen wir den gelesenen
                // String aber erst wieder zurück in den Stream schieben,
                // und zwar zeichenweise rückwärts.
                std::for_each(
                    token.rbegin(), token.rend(),
                    std::bind1st(std::mem_fun(&std::istream::putback), &input)
                );
                int number;
                input >> number;
                stack.push(number);
            }
        }
    
        std::cout << stack.top() << std::endl;
    }
    

    Bis auf die Sache mit 'std::for_each' sollte das alles einigermaßen verständlich sein. Zu dem for_each-Dings ist nur wichtig zu verstehen, dass der String hier rückwärts zeichenweise durchgegangen wird, und für jedes Zeichen wird die Funktion 'putback' auf dem 'input'-Stream aufgerufen, also im Prinzip dasselbe wie 'input.putback(c)', wobei 'c' das aktuelle Zeichen ist.



  • andigr schrieb:

    man man. Habs geändert, aber er meckert immer noch:
    http://666kb.com/i/atfo49qr3tw5hvspx.jpg

    Das dauernde Posten von Screenshots ist doch wohl sowohl für Dich als auch für uns ein wenig aufwendig, oder? Poste doch einfach den relevanten Code + Fehlermeldung. In diesem Fall liegt der Fehler daran, dass Du einen Zeiger auf Zeichen mit einem Zeichen vergleichst, das geht natürlich nicht, hatte ich vorher übersehen. Aber auch ansonsten wird es Fehler geben. Schon die erste Zeile Deiner 'main'-Funktion ist in C++ undefiniert.



  • mhm. Naja, das atoi usw hab ich alles an der uni gelernt... Dein programm ist mir schon etwas zu kompliziert, kenn die hälfte der bibliotheken nicht, drum hätt ich noch ne andere frage:

    Ich habs mal geschaft, auf der konsole die eingegebenen werte wieder auszugeben.

    http://666kb.com/i/atfokxwdxk24fq7mt.jpg

    in der blau unterlegten zeile hat es noch eine if schleife. Wieso ignoriert er diese, wenn er das "minus" zeichen auf der konsole korrekt ausgiebt?



  • ok sorry wegen den screenshots, ich dachte das sei einfach für die hilfe...



  • andigr schrieb:

    mhm. Naja, das atoi usw hab ich alles an der uni gelernt... Dein programm ist mir schon etwas zu kompliziert, kenn die hälfte der bibliotheken nicht, drum hätt ich noch ne andere frage:

    „Die Hälfte der Bibliotheken“ … ich verwende da nur *eine* Bibliothek, nämlich die C++-Standardbibliothek. Und wenn Du die noch nicht kennst, wird es Zeit. Alles andere ist unwichtig.

    Allerdings sind die letzten zwei Header wirklich Overkill, dieses for_each-Ding (dafür brauche ich die) kann man auch einfacher machen:

    typedef std::string::const_reverse_iterator It;
    for (It i = token.rbegin(); i != token.rend(); ++i)
        input.putback(*i);
    

    Na ja …

    in der blau unterlegten zeile hat es noch eine if schleife. Wieso ignoriert er diese, wenn er das "minus" zeichen auf der konsole korrekt ausgiebt?

    Weil Du hier Zeiger vergleichst und nicht den String-Inhalt. Das ist eben das Problem, wenn Du Low-Level-Zeiger statt vernünftiger Klassen verwendest. Wenn Du, wie in meinem Code, die std::string-Klasse benutzt, dann hast Du dieses Problem nicht.



  • hi konrad
    vielen dank für deine hilfe. Ich habs nun so halbwegs hinbekommen, und es funktioniert auch gar nicht schlecht.

    also, vielen dank nochmal
    lg


Anmelden zum Antworten