Weshalb funktioniert dieses Programm ohne dabei ein Array zu übertragen ?



  • Hallo zusammen,

    Ich melde mich mal wieder, da einem in diesem Forum meiner Meinung nach immer sehr gut geholfen wird. Dafür nochmal ein großes Dankeschön von meiner Seite.

    Nun komme ich auch zum wesentlichen. Ich habe ein Programm geschrieben, welches eine Zeichenkette entgegen nehmen soll, diese soll dann überprüft werden und einen Wert wiedergeben. Sobald ich Ziffern eintippe werden diese dann gezählt.

    Mein Problem dabei ist, dass ich eine Zeichenkette als Char initialisiere und sie mit gets() einfangen möchte, dass sollte in der Theorie auch funktionieren, wenn Visual Studio in der Praxis nicht wegen unsicheren Funktionen meckern würde ;).
    ICh habe dann einfach mal versucht dieses gets(zeichenkette) wegzulassen, und (ich kann es mich auch nicht erklären) das Programm funktioniert, aber wie kann das sein ? Es wird doch nichts in die Funktion geschrieben ?

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    int anzahlZiffern(char *s);
    
    int main(void){
    	// MAX 20 Zeichen
    	printf("Gib Zeichenkette (e=Ende): ");
    	char text[20+1];
    	// gets(text);
    	anzahlZiffern(text);
    
    	system("PAUSE");
    	return 0;
    }
    
    int anzahlZiffern(char *s){
    	int z;
    	int nz = 0;
    	z = getchar();
    	// printf("Gib Zeichenkette (e=Ende): ");
    	while (1) {
    		z = getchar();
    		if (z >= '0' && z <= '9'){
    			nz++;
    		}
    		if (z == 'e'){
    			printf("Programmende  \n");
    			break;
    		}
    		if (z == '\n'){
    			printf("Die Zeichenkette enthaelt %d Ziffern\n", nz);
    			nz = 0;
    			printf("Gib Zeichenkette (e=Ende): ");
    		}
    	}
    }
    

    Die Ausgabe soll in etwa so aussehen:

    Gib Zeichenkette (e=Ende):  1234
    Die Zeichenkette enthaelt 4 Ziffern
    Gib Zeichenkette (e=Ende):  3
    .....
    

    // soll sich solange wiederholen, bis Nutzer e drückt.

    Wenn mir jemand diesen Sachverhalt näher erklären könnte, wäre das sehr nett. Danke schon mal vorab.



  • Du liest doch jedes Zeichen einzeln ein und überprüfst es..
    Und s benutzt du in deiner Funktion doch eh nicht.

    Visual Studio meckert gerne, auch zu Unrecht. Aber bei gets hat es Recht.
    gets ist in der neusten C-Version (C11) auch nicht mehr dabei.



  • c-Fragensteller schrieb:

    Ich habe ein Programm geschrieben, welches eine Zeichenkette entgegen nehmen soll, diese soll dann überprüft werden und einen Wert wiedergeben. Sobald ich Ziffern eintippe werden diese dann gezählt.

    Falsch. Du nimmst nicht einen Wert entgegen, sondern du ließt ihn von der Standardeingabe ein, und dieser Wert (nennen wir ihn mal "String") soll nur Ziffern beinhalten. Und am Ende, wenn der User ein 'e' angegeben hat, soll die Schleife die Anzahl der Ziffern im String ausgeben.

    c-Fragensteller schrieb:

    Mein Problem dabei ist, dass ich eine Zeichenkette als Char initialisiere und sie mit gets() einfangen möchte, dass sollte in der Theorie auch funktionieren, wenn Visual Studio in der Praxis nicht wegen unsicheren Funktionen meckern würde ;).

    Da hat VS auch verdammt recht mit. Wenn dein Lehrer ernsthaft den Nutzen von gets empfiehlt, ist er ein Scharlatan und als Lehrer ungeeignet.

    c-Fragensteller schrieb:

    ICh habe dann einfach mal versucht dieses gets(zeichenkette) wegzulassen, und (ich kann es mich auch nicht erklären) das Programm funktioniert, aber wie kann das sein ? Es wird doch nichts in die Funktion geschrieben ?

    Im Deutschen gibt es Präpositionen, deren Verwendungen nicht trivial sind. Wenn du etwas "in die Funktion" schreibst, ist das nicht so gut, weil du damit deinen eigenen Code überschreibst. Meistens bekommst du dabei aber eh einen Fehler, weil die Hardware Schreibschutz bestimmter Speicherbereiche kennt.

    Was du eher meinst, ist "in der Funktion wird nichts in den Speicherblock, den du in main übergibst, geschrieben". Und das braucht du ja auch nicht. Siehe DirkB: Zeichen einzeln prüfen, Ziffern einzeln mitzählen. Abgesehen von der Struktur des Programmcodes gibt es wenig, was ich bei deinem Ansatz anders machen würde.

    Noch einmal:

    - Einzelnes Zeichen wird von stdin geholt.
    - Zeichen wird verglichen: wenn 'e', werden alle Ziffern bis hierhin ausgegebenen und die Schleife neu initialisiert. Wenn Ziffer, dann wird Ziffernzähler hochgesetzt. Wenn etwas anderes, wird es ignoriert.

    Da braucht es kein gets . Nicht mal in der Programmiererhölle.



  • Super, das habe ich soweit verstanden. Danke.

    Ich habe dann noch eine weitere Frage zur while Schleife mit 3 Bedingungen, ich möchte dazu keinen neuen Thread aufmachen. Ich denke auch, dass das schnell beantwortet werden kann:

    Mein Problem ist, dass ich zum einen jede Zahl zwei mal eingeben muss, zum anderen kann ich zwar 2. Berechnen lassen, wenn ich dann aber in 3. springen möchte funktioniert dies nicht, ich kann jedoch in 5. springen ? Warum ? und wie kann ich das lösen ?

    #include <stdio.h>
    #include <stdlib.h>
    
    float celsinfahr(float celsius);
    float fahrincels(float fahrenheit);
    
    int main(void){
    
    	printf("Hallo geben sie irgendwas ein...\n");
    
    	float anfangstemp;
    	anfangstemp = 40.0;
    	float endtemp;
    	endtemp = 50.0;
    	float schritte;
    	schritte = 0.5;
    
    	int c;
    	c = getchar();
    
    	//char read;
    	//scanf_s("%c", &read);
    
    	while (c = getchar()){
    
    		if (c == '2'){
    			for (anfangstemp; anfangstemp <= endtemp;){
    
    				printf("Celsius %f\t	Fahrenheit %f\t\n", anfangstemp, celsinfahr(anfangstemp));
    				anfangstemp = anfangstemp + schritte;
    				celsinfahr(anfangstemp));
    			}
    		}
    
    		if (c == '3'){
    			for (anfangstemp; anfangstemp <= endtemp;){
    
    				printf("Celsius %f\t	Fahrenheit %f\t\n", anfangstemp, fahrincels(anfangstemp));
    				anfangstemp = anfangstemp + schritte;
    				celsinfahr(anfangstemp));
    			}
    		}
    
    		if (c == '5'){
    			printf("ENDE");
    			break;
    		}
    	}
    	system("PAUSE");
    	return 0;
    }
    
    float celsinfahr(float celsius){
    	return (celsius * 1.8 + 32.0);
    }
    
    float fahrincels(float fahrenheit){
    	return ((5.0 / 9.0)*(fahrenheit - 32.0));
    }
    

    Danke für die sehr kompetenten Antworten ! 🙂



  • Das ist uncompilierbarer Code. Copy+Paste ist wohl zu schwierig für dich.
    Was soll Zeile 33 bewirken?
    Zeile 32 gehört mit ins for von Zeile 29 usw.
    Du hast getchar() immer noch nicht verstanden, sonst würdest du sowas Sinnfreies nicht anbieten.
    Hast du schon mal was von switch/case gehört?
    printf("...\t\n") ist ebenso sinnfrei.



  • @Wutz ich finde es sehr schade, dass du hier so "persönlich" wirst...
    Aber dennoch kann ich dich verstehen, ich habe hier im Forum Editor sozusagen manuell meine Kommentare entfernt und hier sind mir schwere Fehler unterlaufen. Entschuldige.

    // celsinfahr(anfangstemp));

    Switch Case ist eigentlich meine erste Wahl für dieses Programm gewesen... Aber generell würde mich interessieren, warum dies in der While nur bedingt funktioniert.



  • Du verwendest 2x getchar() , warum?
    Weil du ohne Überlegung irgendwas hinschreibst und froh bist, dass der Compiler das annimmt.



  • Okay, ich denke, dass ich es jetzt hab. Ich hab einfach nochmal neu angefangen und von vorne überlegt, dieses mal mit mehr Sinn und Verstand 😉

    @Wutz auch wenn ich mich von deinem "harten" Ton etwas angegriffen fühle, verstehe ich deinen Einwand, etwas nur auf "Gut Glück" programmieren bringt nichts, man sollte vorher genau überlegen. Daher neuer Ansatz mehr Verstand und die Sache läuft jetzt... 🙂


Log in to reply