upn taschenrechner (ascii problem)



  • Hi zusammen.
    Ich hab eine kleine frage zu den ascii zeichen. Und zwar muss ich ein taschenrechner (upn) programmieren, der zahlen und die rechenoperationen (+,-,/,) einliest. Das ganze soll von der konsole als argumentenliste eingelesen werden. Die argumentenliste wird mit "atoi" in integerwerte umgewandelt. Ich muss nun eine if schleife programmieren, wo getestet werden soll, ob der getestete wert ein +,-,/, zeichen ist. Wie muss ich das genau machen? Mit ascii code?



  • http://www.if-schleife.de/

    Zu deinem Problem:

    if (dein_zeichen == '+')
      // mache ne Addition
    else if (deine_zeichen == '-')
      // mache ne Subtraktion
    

    Gruss,
    DeSoVoDaMu



  • in diesem falle wäre sogar ein switch-case ansehlich

    genau wie in der aufgabe gedacht war, die unsere Erstis zum Thema Taschenrechner bekommen haben 😉



  • ok, ich habs mal mit dem if (num[i] = '+'){... probiert. geht aber nicht so recht. Hier mal mein code und die konsoleausgabe: Also wenn ich ein + eingebe, solle er "plus" ausschreiben, was er aber nicht tut...

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



  • Kleiner tipp - oder + ascii bleiben sollte. ^^

    Du macht da glaub ein Chr-wert.



  • isiprimax schrieb:

    Kleiner tipp - oder + ascii bleiben sollte. ^^

    Du macht da glaub ein Chr-wert.

    miam, sorry, aber das hab ich jetzt nicht ganz verstanden den tipp 😉



  • Du musst eine If-Abfrage einbauen, das einliest was eine zahl ist die dann mit "atoi" umgewandelt wird. Und was ein Ascii bleiben soll wie zb + - * / usw...

    Glaub wen du + atoi machst bekommste den keycode.



  • hmm. aber ich muss ja die ganze argumentenliste zuerst in integer werte umwandeln, damit ich überhaupt entscheiden kann ob es sich um eine zahl oder um einen operanden handelt. Wie kann ich dann einen operand wieder zurückwandeln?

    gruss



  • einzelne chars vergleichen geht einfach mit ==:

    char c = '+';
    if(c == '+')
       do_bla();
    

    Bei arrays:

    char c[] = "abcd";
    if(c[0] == 'a')
        //true
    


  • ja, schon klar, aber ich hab ja eine argumentenliste wie zb: "4 2 3 + /". Diese wandle ich in integers um, und speichere sie in einem array. Wie kann ich aber in dem array prüfen, ob nun zb bei array[i] ein "+" abgespeichert ist?

    gruss



  • Habs eben mal getestet.

    #include <iostream>
    
    using namespace std;
    
    int main(int argc, char* argv[])
    {
        int a;
        for(int i=0; i<argc; i++)
        {
            a = atoi(argv[i]);
            cout << a << " : " << argv[i] << endl;
        }
        return 0;
    }
    

    Ascii zeichen sind 0.



  • genau... Aber weiterhelfen tuts mir irgendwie doch nicht so recht 😞



  • 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?


Anmelden zum Antworten