Rechner will nicht so richtig



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



  • player4245 schrieb:

    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.

    1. Wenn dann kann man gleich 42 schreiben, weil das '*' ist.
    2. Sind das nicht meine Funktionen, ist schon klar oder? Ich hab einfach die vorhandenen Routinen etwas zurecht gestutzt, mehr nicht.



  • FrEEzE2046 schrieb:

    player4245 schrieb:

    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.

    1. Wenn dann kann man gleich 42 schreiben, weil das '*' ist.
    2. Sind das nicht meine Funktionen, ist schon klar oder? Ich hab einfach die vorhandenen Routinen etwas zurecht gestutzt, mehr nicht.

    1. Das macht aber niemand, der produktiven und gut wartbaren Code schreiben will, da Code für sich selber sprechen soll.

    Das heißt auch, dass man "Magic Numbers" vermeiden soll. Und ob mit 42 jetzt die Antwort "nach dem Leben, dem Universum und dem ganzen Rest" gemeint ist oder ein ASCII-Zeichen, weiß nach einigen Monaten auch niemand mehr.

    Und wenn man dann jedes Mal in einer ASCII-Tabelle nachgucken muss, dann dauert das Verstehen des Codes unnötig länger. Alles nur, weil man "cool" sein wollte und nicht das verständlichere '*' schreiben wollte.


Anmelden zum Antworten