Rechner will nicht so richtig



  • Hallo Leute,

    das ärgerliche ist leider, dass ich das Programm schon längst fertig hatte aber leider sollte ich ein paar Alghoritmen u.a. weglassen. Aus einem komplizierten zum leichten sozusagen. Jetzt geht gar nichts mehr und es wird immer schlimmer. Ich hoffe auf einen Rat von euch, wäre sehr nett.

    Zuerst zum Programm: Das Programm soll +.-,* und / berechnen können sowie einige andere kleiner Funktionen. Zudem soll alles über einen Stack erfolgen, also einlesen der Variablen und in den Stack abspecihern sowie vom Stack wieder runterholen und berechnen.Das Hauptproblem besteht darin, dass +.-,*,/ ein char ist und Zahlen nunmal int/double. Zuerst das Zeichen einlesen, auf ENTER warten, umwandeln von char nach double und prüfen ob die dies im Intervall von 0 bis 9 liegt. Die Methode calc bekommt den originalen String.

    Wir sollen nur fgets, snprintf usw. wegen der Sicherheit damit nichts überschrieben wird.

    Nicht wundern der Code ist jetzt leider ziemlich demoliert, war ziemlich gefrustet und wurde immer schlimmer und eine kleine Pause half leider auch nicht. 😞 Entschuldigung



  • Was ist das?

    #ifndef STACK_
    #define STACK_
    
    #endif /*STACK_*/
    
    double pop();
    void push(double s);
    int size();
    int getPos();
    

    Nicht dein ernst:

    #define max 1;
    char string[max];
    

    Das würde ich noch erweitern:

    int StrToInt(char *str)
    {
    	return atoi(str);
    }
    

    in:

    int StrToIntEx(char* str)
    {
    	return StrToInt(str);
    }
    
    Das Programm soll +.-,* und / berechnen können
    

    Du meinst, das Programm soll Zahlen addieren, subtrahieren usw. können? Hat das Programm denn irgendwann mal funktioniert. Der Code hat an allen Ecken und kannten Probleme.



  • FrEEzE2046 schrieb:

    Das würde ich noch erweitern:

    int StrToInt(char *str)
    {
    	return atoi(str);
    }
    

    in:

    int StrToIntEx(char* str)
    {
    	return StrToInt(str);
    }
    

    du bist ja ein ganz großer seher in deinem stamm 😃 👍

    lg lolo



  • noobLolo schrieb:

    du bist ja ein ganz großer seher in deinem stamm 😃 :live

    Tja, wenn's irgendwo was zu optimieren gibt sticht mir das sofort ins Auge 😉

    Wenn, dann ansatzweiße so:

    int main(void) 
    {
    	char in;
    
    	setvbuf(stdin, NULL, _IONBF, 0);
    	setvbuf(stdout, NULL, _IONBF, 0);
    
    	// sehr nett
    	printf("Bitte geben Sie ein: ");
    
    	while( 1 )
    	{
    		in = fgetc(stdin);
    		if( in >= 48 && in <= 57 )
    			push(in);
    		else	if( !(getPos() + 1) )
    			printf("stack ist leer\n");
    
    		/* 
    		Umstand:
    		fgets(&in, 1, stdin);
    		getchar();
    		*/
    
    		/*
    		Dein Eingabepuffer umfasst ein ganzes Byte 
    		man kann gar keine Gleitkommazahl eingeben.
    		a = atof(&in);
    		*/
    
    		/*
    		Wozu?
    		printf("%d", a);
    		*/
    
    		/*
    		Grundsätzlich würde ich nie double Werte vergleichen
    		Hier sowieso nicht
    		if( a >= 0 || a <= 9 )
    			push(a);
    		*/
    
    		// calc(in);
    	}
    
    	return 0;
    }
    

    Wann du calc() aufrufen willst ist mir aber schleierhaft. Soll wirklich immer nur ein Zeichen eingegeben werden können?
    Zudem: Wo speicherst du die Operatoren? Kann ich immer nur 2 Zahlen verrechnen? Aber warum wird auch schon nach der ersten Eingabe calc() aufgerufen? Weshalb der "Stack"?

    Was soll das Programm eigentlich können?



  • hoth schrieb:

    Hier das gesamte Projekt: Hier Klicken! (arcor, Projekt1.rar)

    Denk mal darüber nach, ob es gut ist, halboffene Protokolle zu verwenden.
    🙂



  • danke



  • Nur noch mal so ein genereller Tipp:

    Es ist ziemlich sinnfrei solche Abfragen zu verwenden:

    if( c == 'A' )
    {
    
    }
    if( c == 'B' )
    {
    
    }
    if( c == 'C' ) 
    {
    
    }
    /* ... */
    

    so hast du es nämlich in calc() gemacht. Denk mal darüber nach und du wirst feststellen, dass es reichlich sinnfrei ist zu Fragen ob c = 'A' und wenn dem so ist noch zu fragen ob es nicht doch vielleicht 'B' ist.

    Bei Zeichenketten wäre ein else if() {} zu verwenden. Ansonsten natürlich switch().



  • FrEEzE2046 schrieb:

    Das würde ich noch erweitern:

    int StrToInt(char *str)
    {
    	return atoi(str);
    }
    

    in:

    int StrToIntEx(char* str)
    {
    	return StrToInt(str);
    }
    

    Ha! Ich krieg mich nicht mehr ein... 😃 👍



  • Mh, danke Leute für eure Hilfe aber irgentwie nehmt ihr mich nicht wirklich ernst. Ich weiß das mein Programm wirklich beschissen ist, dass kommt dadurch das ich noch ein ziemlicher Anfänger bin und ich mich erstmal einarbeiten muss.

    Mein Hauptproblem bestand eingentlich darin das ich die int z.B. 43 wieder in ein char umwandeln kann. Das macht er leider nicht so wie ich wollte und dann habe ich das Programm komplett geschrottet zzgl. halt auch einen Alghoritmus den ich eingebaut hatte, der nicht in der Aufgabenstellung gefordert war. Funktioniert hatte aber.

    Ich hätte das Programm vielleicht nicht hochladen sollen.

    Tut mir Leid euch damit zu nerven.



  • Ich hätte da noch eine verschärfte Version ist aber C++. Musst mal schauen wie der Compiler mitspielt. Evtl. musst du da ein wenig tricksen. Ansonsten geht da richtig die Post ab:

    #include <iostream>
    using namespace std;
    
    typedef int (*LP_ATOI)(const char*);
    
    template<LP_ATOI func>
    int IntToStr(const char* c)
    {
    	return IntToStr<func>(c);
    }
    
    int main()
    {
    	char c = 65;
    	cout << IntToStr<atoi>(&c) << endl;
    
    	return 0;
    }
    


  • hoth schrieb:

    Mein Hauptproblem bestand eingentlich darin das ich die int z.B. 43 wieder in ein char umwandeln kann.

    Ist doch gut, wenn du's kannst. Wo liegt das Problem? Ich kann's auch und komm damit klar:

    int main()
    {
    	char c[2];
    	itoa(43, c, 10);
    
    	return 0;
    }
    

    Das Hauptproblem ist, dass du uns den Source hier hinknallst und quasi sagst "Macht mal."
    Da brauchst du dich nicht wundern, wenn wir uns ein wenig darüber amüsieren. Zumal es zum Teil krasse Fehler in deinem Code gibt, der in deiner Form bei mir überhaupt nicht kompiliert, sondern 15+ Compiler-Fehler schmeißt.

    Außerdem ist überhaupt nicht klar, was das ganze letztendlich werden soll und was nicht. Ich denke mal du willst einen Taschenrechner über Konsole programmieren, der +,-,*,/ Operationen beherrscht.

    Das Problem ist, dass dein Source weit davon entfernt ist das zu können und niemand wird sich hier hinsetzen und das Ding für dich programmieren.

    Stell lieber konkrete Fragen zu einzelnen Problemen und präsentier kein "Problem-Projekt". Ist nicht im geringsten böse gemeint, aber so kommst du dann auch zum Ziel.



  • Ok das war nicht schlau von mir, ich wollte auch nicht das ihr das für mich schreibt. Ich wollte nur wissen wie das mit der Konvertierung gehen könnte. Hatte dann gedacht, weil viele dan den Code selber sehen wollen, lade ich es einfach mal hoch.

    Das Programm soll folgendes können:
    -> umgekehrte polnische Notation.
    +,-,*,/ -> Operationen berechnen können.
    Die zu berechneten Zahlen in den Stack speichern, in einer calc()-Methode dann die Werte wieder aus dem Stack holen und berechnen. Den berechneten Wert wieder auf den Stack packen.

    Beispiel

    3 4 5 + (eingegeben)
    3 5 5 werden auf den Stack gespeichert.
    nach der calc()-Methode:
    Stack: 3 9

    Ja, es ist noch weit davon entfernt. 🙂



  • Also soll im Endeffekt nur etwas gemacht wenn mind. 2 Zahlen im Stack sind, richtig?

    Die Frage ist, was bringt das? Du hast die 3 (in deinem Beispiel) dann unveränderbar drin. Vor allem weil nicht klar wird, wann du den Stack leeren willst oder soll das gar nicht passieren? Wäre dann im wahrsten Sinne ein StackOverflow.



  • Da musst du den Aufgabensteller fragen, ich soll einen Taschenrechner schreiben der den ersten und zweiten Wert berechnet und das ergebnis wieder auf den Stack legt. Zumindest habe ich die upn so verstanden.



  • int main(void) 
    {
    	char in;
    
    	setvbuf(stdin, NULL, _IONBF, 0);
    	setvbuf(stdout, NULL, _IONBF, 0);
    
    	while( 1 )
    	{
    		printf("Bitte geben Sie ein: ");
    
    		fflush(stdin);
    		in = fgetc(stdin);
    		if( in >= 48 && in <= 57 )
    			push(in);
    		else 
    			calc(in);
    	}
    
    	return 0;
    }
    
    void calc(char c)
    {
    	int sum = 0;
    
    	switch( c )
    	{
    	case 42:		// '*'
    		push(sum = pop() * pop());
    		break;
    	case 43:		// '+'
    		push(sum = pop() + pop());
    		break;
    	case 45:		// '-'
    		push(sum = pop() - pop());
    		break;
    	case 47:		// '/'
    		push(sum = pop() / pop());	
    	}		
    
    	printf("Ergebnis = %d\n", sum);
    }
    
    char stack[200];
    int pos = -1;
    
    char pop()
    {
    	char ret_val = stack[pos];
    	stack[pos--] = 0;
    	return ret_val;
    }
    
    void push(char s){
        stack[++pos] = s;
    }
    
    int size(){
    	if(pos == -1){
    		return 0;
    	}else{
    		return (pos+1);
    	}
    }
    
    int getPos(){
    	return pos;
    }
    


  • FrEEzE2046 schrieb:

    printf("Bitte geben Sie ein: ");
    
    		fflush(stdin);
    		in = fgetc(stdin);
    

    Hmmm. Schon wieder eine Wolfroutine.
    🙂



  • #include <stdio.h>
    
    #define STACK_LIMIT (1000)
    
    typedef struct
    {
    	char data[STACK_LIMIT];
    	int stackPtr;
    } Stack;
    
    void stackInit(Stack *stack)
    {
    	stack->stackPtr = 0;
    }
    
    void stackPush(Stack *stack, int val)
    {
    	++(stack->stackPtr);
    
    	stack->data[stack->stackPtr] = val;
    }
    
    int stackPop(Stack *stack)
    {
    	int val = stack->data[stack->stackPtr];
    
    	--(stack->stackPtr);
    
    	return val;
    }
    
    void stackPushOp(Stack *stack, char op)
    {
    	int right = stackPop(stack);
    	int left = stackPop(stack);
    
    	int res;
    
    	switch (op)
    	{
    		case '+':
    			res = left + right;
    			break;
    
    		case '-':
    			res = left - right;
    			break;
    
    		case '*':
    			res = left * right;
    			break;
    
    		case '/':
    			res = left / right;
    			break;
    	}
    
    	stackPush(stack, res);
    }
    
    void stackPrint(Stack *stack)
    {
    	int i;
    
    	printf("--- Stack ---\n");
    
    	for (i = 0; i < stack->stackPtr; ++i)
    	{
    		printf("%i\t%i\n", i, stack->data[i]);
    	}
    
    	printf("\n");
    }
    
    #define STACK_ADD(x) stackPushOp(x, '+')
    #define STACK_SUB(x) stackPushOp(x, '-')
    #define STACK_MUL(x) stackPushOp(x, '*')
    #define STACK_DIV(x) stackPushOp(x, '/')
    
    int main()
    {
    	Stack stack;
    
    	stackInit(&stack);
    	stackPush(&stack, 3);
    	stackPush(&stack, 4);
    	stackPush(&stack, 5);
    
    	stackPrint(&stack);
    
    	STACK_ADD(&stack);
    
    	stackPrint(&stack);
    }
    

    Komme allerdings aus dem C++ Bereich und programmiere normalerweise nicht in C. War mal ein Test, ob ich das auch kann 😃



  • anstatt

    case 42:        // '*'
    

    kann man auch gleich schreiben

    case '*':
    

    Und von wegen Funktionsdeklarationen 😉 du glänzt auch nicht durch Profiwissen also musst du nicht andere runtermachen.



  • Hab ein Fehler drinne. So ists richtig:

    void stackInit(Stack *stack)
    {
    	stack->stackPtr = -1;
    }
    

    und

    void stackPrint(Stack *stack)
    {
    	int i;
    
    	printf("--- Stack ---\n");
    
    	for (i = 0; i <= stack->stackPtr + 1; ++i)
    	{
    		printf("%i\t%i\n", i, stack->data[i]);
    	}
    
    	printf("\n");
    }
    


  • xcvsdfsdf schrieb:

    Hab ein Fehler drinne. So ists richtig:

    void stackInit(Stack *stack)
    {
    	stack->stackPtr = -1;
    }
    

    und

    void stackPrint(Stack *stack)
    {
    	int i;
    
    	printf("--- Stack ---\n");
    
    	for (i = 0; i <= stack->stackPtr + 1; ++i) // Das + 1 weg.
    	{
    		printf("%i\t%i\n", i, stack->data[i]);
    	}
    
    	printf("\n");
    }
    

    Argh. Das +1 muss noch weg. Ich hasse meine Tastatur. Die klemmt immer und hab noch altes Zeugs in der Zwischenablage, sorry.


Anmelden zum Antworten