Probleme mit dem Taschenrechner von Stroustrup



  • Hi,

    Ich wollte den Taschenrechner von Stroustrup mal nachprogrammieren (=zuerst mal abschreiben :D), nur gibt es da mit diesem Quelltext ein großes und 10 kleine Probleme:

    #include <iostream>
    #include <map>
    #include <string>
    #include <cctype>
    using namespace std;
    
    enum TokenValue {
    	NAME,			NUMBER,				END,
    	PLUS = '+',		MINUS = '-',		MUL = '*',			DIV = '/',
    	PRINT = ';',	ASSIGN = '=',		LP = '(',			RP = ')'
    };
    
    TokenValue curr_tok = PRINT;
    double number_value;
    string string_value;
    int no_of_errors;
    map<string, double> table;
    
    double expr(bool);
    double prim(bool);
    double term(bool);
    TokenValue get_token();
    
    double error(const string& s)
    {
    	no_of_errors++;
    	cerr << "Fehler: " << s << endl;
    	return 1;
    }
    
    double expr(bool get)
    {
    	double left = term(get);
    	for (;;)
    		switch (curr_tok) {
    		case PLUS:
    			left += term(true);
    			break;
    		case MINUS:
    			left -= term(true);
    			break;
    		default:
    			return left;
    		}
    }
    
    double term(bool get)
    {
    	double left = prim(get);
    	for (;;)
    		switch(curr_tok) {
    		case MUL:
    			left *= prim(true);
    			break;
    		case DIV:
    			if (double d = prim(true)) {
    				left /= d;
    				break;
    			}
    			return error("Division durch 0");
    		default:
    			return left;
    		}
    }
    
    double prim(bool get)
    {
    	if (get)
    		get_token();
    
    	switch (curr_tok) {
    	case NUMBER:
    		{
    			double v = number_value;
    			get_token();
    			return v;
    		}
    	case NAME:
    		{
    			double& v = table[string_value];
    			if (get_token() == ASSIGN)
    				v = expr(true);
    			return v;
    		}
    	case MINUS:
    		return -prim(true);
    	case LP:
    		{
    			double e = expr(true);
    			if (curr_tok != RP)
    				return error(") erwartet");
    			get_token();
    			return e;
    		}
    	default:
    		return error("primary erwartet");
    	}
    }
    
    TokenValue get_token()
    {
    	char ch;
    	do {
    		if (!cin.get(ch))
    			return curr_tok = END;
    	} while (ch != '\n' && isspace(ch));
    	switch (ch) {
    	case ';':
    	case '\n':
    		return curr_tok = PRINT;
    	default:
    		if (isalpha(ch)) {
    			string_value = ch;
    			while (cin.get(ch) && isalnum(ch))
    				string_value.push_back(ch); //ERROR!!!
    			cin.putback(ch);
    			return curr_tok = NAME;
    		}
    		error("Falsches Token");
    		return curr_tok = PRINT;
    	}
    }
    

    Allerdings kennt mein VC++ 6 kein string::push_back(char) 😕
    Weiterhin gibt er 10 Warnungen zu der Map aus 😮:

    --------------------Configuration: taschenrechner - Win32 Debug--------------------
    Compiling...
    rechner.cpp
    f:\programme\microsoft visual studio\vc98\include\xtree(120) : warning C4786: 'std::_Tree<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::pair<std::basic_string<char,std::char_traits<char>,std::allocator<char> > const ,doub
    le>,std::map<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,double,std::less<std::basic_string<char,std::char_traits<char>,std::allocator<char> > >,std::allocator<double> >::_Kfn,std::less<std::basic_string<char,std::char_trait
    s<char>,std::allocator<char> > >,std::allocator<double> >' : identifier was truncated to '255' characters in the debug information
    f:\programme\microsoft visual studio\vc98\include\map(46) : see reference to class template instantiation 'std::_Tree<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::pair<std::basic_string<char,std::char_traits<char

    ,std::allocator<char> > const ,double>,std::map<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,double,std::less<std::basic_string<char,std::char_traits<char>,std::allocator<char> > >,std::allocator<double> >::_Kfn,std::less<st
    d::basic_string<char,std::char_traits<char>,std::allocator<char> > >,std::allocator<double> >' being compiled
    F:\Projekte\taschenrechner\rechner.cpp(17) : see reference to class template instantiation 'std::map<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,double,std::less<std::basic_string<char,std::char_traits<char>,std::all
    ocator<char> > >,std::allocator<double> >' being compiled
    f:\programme\microsoft visual studio\vc98\include\xtree(120) : warning C4786: 'std::_Tree<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::pair<std::basic_string<char,std::char_traits<char>,std::allocator<char> > const ,doub
    le>,std::map<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,double,std::less<std::basic_string<char,std::char_traits<char>,std::allocator<char> > >,std::allocator<double> >::_Kfn,std::less<std::basic_string<char,std::char_trait
    s<char>,std::allocator<char> > >,std::allocator<double> >::const_iterator' : identifier was truncated to '255' characters in the debug information
    f:\programme\microsoft visual studio\vc98\include\map(46) : see reference to class template instantiation 'std::_Tree<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::pair<std::basic_string<char,std::char_traits<char
    ,std::allocator<char> > const ,double>,std::map<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,double,std::less<std::basic_string<char,std::char_traits<char>,std::allocator<char> > >,std::allocator<double> >::_Kfn,std::less<st
    d::basic_string<char,std::char_traits<char>,std::allocator<char> > >,std::allocator<double> >' being compiled
    F:\Projekte\taschenrechner\rechner.cpp(17) : see reference to class template instantiation 'std::map<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,double,std::less<std::basic_string<char,std::char_traits<char>,std::all
    ocator<char> > >,std::allocator<double> >' being compiled
    f:\programme\microsoft visual studio\vc98\include\xtree(120) : warning C4786: 'std::_Tree<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::pair<std::basic_string<char,std::char_traits<char>,std::allocator<char> > const ,doub
    le>,std::map<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,double,std::less<std::basic_string<char,std::char_traits<char>,std::allocator<char> > >,std::allocator<double> >::_Kfn,std::less<std::basic_string<char,std::char_trait
    s<char>,std::allocator<char> > >,std::allocator<double> >::iterator' : identifier was truncated to '255' characters in the debug information
    f:\programme\microsoft visual studio\vc98\include\map(46) : see reference to class template instantiation 'std::_Tree<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::pair<std::basic_string<char,std::char_traits<char
    ,std::allocator<char> > const ,double>,std::map<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,double,std::less<std::basic_string<char,std::char_traits<char>,std::allocator<char> > >,std::allocator<double> >::_Kfn,std::less<st
    d::basic_string<char,std::char_traits<char>,std::allocator<char> > >,std::allocator<double> >' being compiled
    F:\Projekte\taschenrechner\rechner.cpp(17) : see reference to class template instantiation 'std::map<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,double,std::less<std::basic_string<char,std::char_traits<char>,std::all
    ocator<char> > >,std::allocator<double> >' being compiled
    f:\programme\microsoft visual studio\vc98\include\xtree(120) : warning C4786: 'std::_Tree<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::pair<std::basic_string<char,std::char_traits<char>,std::allocator<char> > const ,doub
    le>,std::map<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,double,std::less<std::basic_string<char,std::char_traits<char>,std::allocator<char> > >,std::allocator<double> >::_Kfn,std::less<std::basic_string<char,std::char_trait
    s<char>,std::allocator<char> > >,std::allocator<double> >::_Node' : identifier was truncated to '255' characters in the debug information
    f:\programme\microsoft visual studio\vc98\include\map(46) : see reference to class template instantiation 'std::_Tree<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::pair<std::basic_string<char,std::char_traits<char
    ,std::allocator<char> > const ,double>,std::map<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,double,std::less<std::basic_string<char,std::char_traits<char>,std::allocator<char> > >,std::allocator<double> >::_Kfn,std::less<st
    d::basic_string<char,std::char_traits<char>,std::allocator<char> > >,std::allocator<double> >' being compiled
    F:\Projekte\taschenrechner\rechner.cpp(17) : see reference to class template instantiation 'std::map<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,double,std::less<std::basic_string<char,std::char_traits<char>,std::all
    ocator<char> > >,std::allocator<double> >' being compiled
    f:\programme\microsoft visual studio\vc98\include\xtree(120) : warning C4786: 'std::_Tree<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::pair<std::basic_string<char,std::char_traits<char>,std::allocator<char> > const ,doub
    le>,std::map<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,double,std::less<std::basic_string<char,std::char_traits<char>,std::allocator<char> > >,std::allocator<double> >::_Kfn,std::less<std::basic_string<char,std::char_trait
    s<char>,std::allocator<char> > >,std::allocator<double> >::const_iterator' : identifier was truncated to '255' characters in the debug information
    f:\programme\microsoft visual studio\vc98\include\map(46) : see reference to class template instantiation 'std::_Tree<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::pair<std::basic_string<char,std::char_traits<char
    ,std::allocator<char> > const ,double>,std::map<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,double,std::less<std::basic_string<char,std::char_traits<char>,std::allocator<char> > >,std::allocator<double> >::_Kfn,std::less<st
    d::basic_string<char,std::char_traits<char>,std::allocator<char> > >,std::allocator<double> >' being compiled
    F:\Projekte\taschenrechner\rechner.cpp(17) : see reference to class template instantiation 'std::map<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,double,std::less<std::basic_string<char,std::char_traits<char>,std::all
    ocator<char> > >,std::allocator<double> >' being compiled
    F:\Projekte\taschenrechner\rechner.cpp(17) : warning C4786: 'std::reverse_bidirectional_iterator<std::_Tree<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::pair<std::basic_string<char,std::char_traits<char>,std::allocator<c
    har> > const ,double>,std::map<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,double,std::less<std::basic_string<char,std::char_traits<char>,std::allocator<char> > >,std::allocator<double> >::_Kfn,std::less<std::basic_string<ch
    ar,std::char_traits<char>,std::allocator<char> > >,std::allocator<double> >::iterator,std::pair<std::basic_string<char,std::char_traits<char>,std::allocator<char> > const ,double>,std::pair<std::basic_string<char,std::char_traits<char>,std::allocato
    r<char> > const ,double> &,std::pair<std::basic_string<char,std::char_traits<char>,std::allocator<char> > const ,double> *,int>' : identifier was truncated to '255' characters in the debug information
    F:\Projekte\taschenrechner\rechner.cpp(17) : warning C4786: 'std::reverse_bidirectional_iterator<std::_Tree<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::pair<std::basic_string<char,std::char_traits<char>,std::allocator<c
    har> > const ,double>,std::map<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,double,std::less<std::basic_string<char,std::char_traits<char>,std::allocator<char> > >,std::allocator<double> >::_Kfn,std::less<std::basic_string<ch
    ar,std::char_traits<char>,std::allocator<char> > >,std::allocator<double> >::const_iterator,std::pair<std::basic_string<char,std::char_traits<char>,std::allocator<char> > const ,double>,std::pair<std::basic_string<char,std::char_traits<char>,std::al
    locator<char> > const ,double> const &,std::pair<std::basic_string<char,std::char_traits<char>,std::allocator<char> > const ,double> const *,int>' : identifier was truncated to '255' characters in the debug information
    F:\Projekte\taschenrechner\rechner.cpp(17) : warning C4786: 'std::pair<std::_Tree<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::pair<std::basic_string<char,std::char_traits<char>,std::allocator<char> > const ,double>,std:
    :map<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,double,std::less<std::basic_string<char,std::char_traits<char>,std::allocator<char> > >,std::allocator<double> >::_Kfn,std::less<std::basic_string<char,std::char_traits<char>,
    std::allocator<char> > >,std::allocator<double> >::iterator,bool>' : identifier was truncated to '255' characters in the debug information
    F:\Projekte\taschenrechner\rechner.cpp(17) : warning C4786: 'std::pair<std::_Tree<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::pair<std::basic_string<char,std::char_traits<char>,std::allocator<char> > const ,double>,std:
    :map<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,double,std::less<std::basic_string<char,std::char_traits<char>,std::allocator<char> > >,std::allocator<double> >::_Kfn,std::less<std::basic_string<char,std::char_traits<char>,
    std::allocator<char> > >,std::allocator<double> >::iterator,std::_Tree<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::pair<std::basic_string<char,std::char_traits<char>,std::allocator<char> > const ,double>,std::map<std::b
    asic_string<char,std::char_traits<char>,std::allocator<char> >,double,std::less<std::basic_string<char,std::char_traits<char>,std::allocator<char> > >,std::allocator<double> >::_Kfn,std::less<std::basic_string<char,std::char_traits<char>,std::alloca
    tor<char> > >,std::allocator<double> >::iterator>' : identifier was truncated to '255' characters in the debug information
    F:\Projekte\taschenrechner\rechner.cpp(17) : warning C4786: 'std::pair<std::_Tree<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::pair<std::basic_string<char,std::char_traits<char>,std::allocator<char> > const ,double>,std:
    :map<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,double,std::less<std::basic_string<char,std::char_traits<char>,std::allocator<char> > >,std::allocator<double> >::_Kfn,std::less<std::basic_string<char,std::char_traits<char>,
    std::allocator<char> > >,std::allocator<double> >::const_iterator,std::_Tree<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::pair<std::basic_string<char,std::char_traits<char>,std::allocator<char> > const ,double>,std::map<
    std::basic_string<char,std::char_traits<char>,std::allocator<char> >,double,std::less<std::basic_string<char,std::char_traits<char>,std::allocator<char> > >,std::allocator<double> >::_Kfn,std::less<std::basic_string<char,std::char_traits<char>,std::
    allocator<char> > >,std::allocator<double> >::const_iterator>' : identifier was truncated to '255' characters in the debug information
    F:\Projekte\taschenrechner\rechner.cpp(115) : error C2039: 'push_back' : is not a member of 'basic_string<char,struct std::char_traits<char>,class std::allocator<char> >'
    Error executing cl.exe.

    taschenrechner.exe - 1 error(s), 10 warning(s)

    Liegt das an den nur zwei "Parametern" in der Deklaration von table? Ist das vll unerheblich? 🙂
    Danke schonmal für die Hilfe 😉



  • Hi

    such mal im forum nach "warning C4786"

    gruß elwida



  • string_value.push_back(ch);
    

    mach daraus

    string_value+=ch;
    


  • Danke schonmal, jetzt bleibt aber noch was über 😕
    Als ich den Text in

    string_value += ch
    

    geändert habe, sind danach 2 neue Errors erschienen. Die Warnungen hab ich dank elwida abgeschaltet bekommen (hattest das Problem ja auch mal :)) ...
    Beim compilen tauchen die neuen Fehler nicht auf, nur beim Erstellen der .exe:

    --------------------Configuration: taschenrechner - Win32 Debug--------------------
    Linking...
    LIBCD.lib(crt0.obj) : error LNK2001: unresolved external symbol _main
    Debug/taschenrechner.exe : fatal error LNK1120: 1 unresolved externals
    Error executing link.exe.

    taschenrechner.exe - 2 error(s), 0 warning(s)

    Mit sowas kenn ich mich leider nicht aus 😞



  • Ich bin dumm 😃
    Hab das Rahmenprogramm vergessen *schäm*
    Sorry für das unnötige Posting 🤡



  • Hmm, ich hab also im Moment keine Compiler-Fehler mehr, allerdings:
    Wenn ich das Programm ausführe, dann kann ich gar nichts machen, überhaupt nichts eingeben ... Da ist einfach nur dieses "Cursor-Feld" ohne, dass irgendeine Eingabe was bewirken würde ... Schließen oder so kann ich es einfach, also aufgehangen hat es sich glaube ich nicht ...
    Hier mal der Code, hoffe auf eure Hilfe 😉 :

    #ifdef _MSC_VER
    	#pragma warning (disable : 4786)
    #endif
    
    #include <iostream>
    #include <string>
    #include <map>
    #include <cctype>
    using namespace std;
    
    enum Token_value {
    	NAME,			NUMBER,				END,
    	PLUS = '+',		MINUS = '-',		MUL = '*',			DIV = '/',
    	PRINT = ';',	ASSIGN = '=',		LP = '(',			RP = ')'
    };
    
    Token_value curr_tok = PRINT;
    double number_value;
    string string_value;
    int no_of_errors;
    map<string, double> table;
    
    double expr(bool);
    double prim(bool);
    double term(bool);
    Token_value get_token();
    
    double error(const string& s)
    {
    	no_of_errors++;
    	cerr << "Fehler: " << s << endl;
    	return 1;
    }
    
    double expr(bool get)
    {
    	double left = term(get);
    	for (;;)
    		switch (curr_tok) {
    		case PLUS:
    			left += term(true);
    			break;
    		case MINUS:
    			left -= term(true);
    			break;
    		default:
    			return left;
    		}
    }
    
    double term(bool get)
    {
    	double left = prim(get);
    	for (;;)
    		switch(curr_tok) {
    		case MUL:
    			left *= prim(true);
    			break;
    		case DIV:
    			if (double d = prim(true)) {
    				left /= d;
    				break;
    			}
    			return error("Division durch 0");
    		default:
    			return left;
    		}
    }
    
    double prim(bool get)
    {
    	if (get)
    		get_token();
    
    	switch (curr_tok) {
    	case NUMBER:
    		{
    			double v = number_value;
    			get_token();
    			return v;
    		}
    	case NAME:
    		{
    			double& v = table[string_value];
    			if (get_token() == ASSIGN)
    				v = expr(true);
    			return v;
    		}
    	case MINUS:
    		return -prim(true);
    	case LP:
    		{
    			double e = expr(true);
    			if (curr_tok != RP)
    				return error(") erwartet");
    			get_token();
    			return e;
    		}
    	default:
    		return error("primary erwartet");
    	}
    }
    
    Token_value get_token()
    {
    	char ch;
    	do {
    		if (!cin.get(ch))
    			return curr_tok = END;
    	} while (ch != '\n' && isspace(ch));
    	switch (ch) {
    	case ';':
    	case '\n':
    		return curr_tok = PRINT;
    	default:
    		if (isalpha(ch)) {
    			string_value = ch;
    			while (cin.get(ch) && isalnum(ch))
    				string_value += ch;
    			cin.putback(ch);
    			return curr_tok = NAME;
    		}
    		error("Falsches Token");
    		return curr_tok = PRINT;
    	}
    }
    
    int main()
    {
    	table["pi"] = 3.1415926535897932385;
    	table["e"] = 2.7182818284590452354;
    
    	while (cin) {
    		if (curr_tok == END) break;
    		if (curr_tok == PRINT) continue;
    		cout << expr(false) << endl;
    	}
    
    	return no_of_errors;
    }
    


  • while (cin) {
            if (curr_tok == END) break;
            if (curr_tok == PRINT) continue;
            cout << expr(false) << endl;
        }
    

    sieht in meinem struppi so aus

    while (cin) {
            get_token ();
            if (curr_tok == END) break;
            if (curr_tok == PRINT) continue;
            cout << expr(false) << endl;
        }
    


  • Im Buch gibt es sicher moegliche Beispieleingaben ... wie du aus dem ganzen rauskommst, ist betriebssystemabhaengig. Unter DOS/Windows Ctrl+Z dann Enter, unter Unix ^D (am Anfang der Zeile). Das loest in cin ein EOF aus.



  • Rauskommen kann ich ja, einfach auf Schließen drücken 😉
    Aber danke SirLant, ich hab wohl die wichtigste zeile einfach vergessen 😡 😉 Klar, dass ich keine Eingaben machen kann, wenn ich die Zeile mit den Eingaben vergessen hab 🙂


Log in to reply