Zum Inhalt springen

Nur auszuwählende Zeichen akzeptieren C


Pizzacorgie28

Empfohlene Beiträge

Moin Leute,

ich soll für mein Studium ein Programm entwickeln wo ich mehrere Auswahl Möglichkeiten habe die durch 1-3 und b gewählt werden können.

Allerdings beendet das Programm sich auch wenn andere Zeichen genutzt werden wie lass ich das programm weiter laufen und abwarten bis eins der 4 Zeichen eingegeben wurde?

Habe mich schon an einer while schleife versucht aber da kann man ja immer nur mit einer Bedienung arbeiten und das hilft mir ja nicht weiter wenn ich wie hier 4 habe?  

Hier der Code soweit:

#include <stdio.h>

int main(void){
	int ceaser=1,vigenere=2,symmetrische=3, auswahl=0;
	char b;
	//char beenden=b; b=98 in ascii tabelle 
	
	
	printf("Herzlich Willkommen\n\nWas wollen Sie tun?\n Drücken sie 1-3 für die jeweilige verschlüsselungs variante\n oder b um das Programm zu beenden\n");
	printf(" (1) Ceasar Verschlüsselung\n (2) Vigenere Verschlüsselung\n (3) Symmetrische Verschlüsselung\n (b) Beenden\n\n");
	//auswahl funktion
	//while (auswahl != 1)
		scanf("%d",&auswahl);
	
	if (auswahl==1) 
		printf("sie haben sich für die Ceasar Verschlüsselung entschieden"); 
	
	else if (auswahl==2)
		printf("sie haben sich für die Vigenere Verschlüsselung entschieden");
		
	else if (auswahl==3)
		printf("sie haben sich für die Symmetrische Verschlüsselung entschieden");
	
	else if (auswahl==b)
		printf("Danke das sie sich für das Programm endschieden haben");
	
	
	
	return 0;
}

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

vor 22 Minuten schrieb Pizzacorgie28:

Habe mich schon an einer while schleife versucht aber da kann man ja immer nur mit einer Bedienung arbeiten und das hilft mir ja nicht weiter wenn ich wie hier 4 habe?  

Gibt ja noch mehr als nur Vergleichsoperatoren. ;)
Aber überlege mal, wie grafische Oberflächen funktionieren. Grafische Oberflächen laufen in einer Endlosschleife. Man könnte auch hier das gleiche Prinzip anwenden. Es wird immer wieder die Eingabe eingelesen, verarbeitet und etwas wird ausgegeben. Wie sieht also eine endlosschleife aus und wie müsstest du deinen Code umstrukturieren?

Schaue auch mal dein scanf() an. Vorallem welches Format deine Eingabe haben muss und welche du erlauben möchtest.

Link zu diesem Kommentar
Auf anderen Seiten teilen

vor 42 Minuten schrieb Whiz-zarD:

Gibt ja noch mehr als nur Vergleichsoperatoren. ;)
Aber überlege mal, wie grafische Oberflächen funktionieren. Grafische Oberflächen laufen in einer Endlosschleife. Man könnte auch hier das gleiche Prinzip anwenden. Es wird immer wieder die Eingabe eingelesen, verarbeitet und etwas wird ausgegeben. Wie sieht also eine endlosschleife aus und wie müsstest du deinen Code umstrukturieren?

Schaue auch mal dein scanf() an. Vorallem welches Format deine Eingabe haben muss und welche du erlauben möchtest.

Danke für die fixe Antwort.

leider wie du wahrscheinlich schon gemerkt hast bin ich noch nube im C Code schreiben :D .

Deswegen äh stehe ich grade ein wenig auf dem schlauch ich habe mich weiter mit while versucht allerdings auch nur mit semi Erfolg.

Scan f habe ich nun auf %i gewechselt was auch mehr sinn macht

scanf("%i", &auswahl) ;
	while (auswahl > 3){
		printf("Bitte eine der oben genannten zeichen eingeben\n");
		scanf("%i", &auswahl) ;
		}

Nun fordert er eine erneut Eingabe wenn man nicht 1-3 wählt, allerdings ist nun leider das Problem das er das Programm nicht nur mit b  beendet sondern auch mit allen anderen Zeichen.

 

 

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

vor einer Stunde schrieb Pizzacorgie28:

aso ok stimmt macht %c mehr sinn für char?

Genau %c ist der korrekte Format specifier für Character Datentypen. In der Dokumentation von der scanf() Methode ist das auch noch mal etwas ausführlicher beschrieben. Die Methode erwartet als Parameter einen const char*. (Wobei die Dokumentation von scanf() zugegebenerweise nicht gerade die intuitivste ist, besonders am Anfang.)

scanf("%d",&auswahl);

Wäre hier also nicht korrekt, weil die Variable auswahl mit dem Datentypen int deklariert wurde. Der Mursk enstand, weil die Daten an der Adresse, die der scanf() Aufruf als ersten Parameter zurück gibt, als char formatiert sind.

int 1; ist beispielsweise die Zahl 1.

char '1'; hingegen ist nur das Zeichen '1' nicht aber der Wert. Intern steht jetzt beispielsweise für '1' der Wert 49 im Speicher das ist der ASCII Wert für das Zeichen '1'. Und da man vorher definiert hat, dass es sich um einen char handelt, weiß die Anwendung das sie es als '1' interpretieren soll.

Praktischerweise hast du aber bereits die char Variable b angelegt, die kann hier übergeben werden.

vor 11 Stunden schrieb Pizzacorgie28:

scanf("%c",&b);

Jetzt sollte auch wieder lesbarer Inhalt in der Variable stehen.

Wenn du den Inhalt der char Variable nun in einen int kopieren möchtest musst du diesen zunächst umwandeln/casten. Zum Beispiel mit einem direkten cast wie folgender:

auswahl = (int)b; 

so wird aber nur der Inhalt von b nach auswahl kopiert, um bei dem Beispiel mit der '1' zu bleiben, steht dann in auswahl die Zahl 49, was aber nicht korrekt ist. Du benötigst also eine andere Lösung, um einen char in einen int umzuwandeln.

vor 10 Stunden schrieb Pizzacorgie28:

while (auswahl > 3){

Würde funktionieren, wenn es nicht noch den 'b' Fall und Zahlen kleiner als 0 gäbe, hier brauchst du also eine andere Unterscheidung, ob die letzte Eingabe nun valide war oder nicht. Um nicht zu viel vorwegzunehmen, nur noch folgender Satz:

Wenn in der Fallunterscheidung in einen der Blöcke gesprungen wird, war die Eingabe valide.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Moin danke für eure hilfe ich habe es jetzt einigermaßen zum laufen bekommen hier die überarbeitete variante.

#include <stdio.h>

int main(void){
	int  ceaser=1, vigenere=2 , symmetrische=3;
	char b=98, auswahl=0;
	//char beenden=b; b=98 in ascii tabelle 
	
	
	printf("Herzlich Willkommen\n\nWas wollen Sie tun?\n Drücken sie 1-3 für die jeweilige verschlüsselungs variante\n oder b um das Programm zu beenden\n");
	printf(" (1) Ceasar Verschlüsselung\n (2) Vigenere Verschlüsselung\n (3) Symmetrische Verschlüsselung\n (b) Beenden\n\n");
	//auswahl funktion hier
	
	while (auswahl != b){
		scanf("%c", &auswahl) ;		
	
		if (auswahl == 49) //49 steht für 1
			printf("sie haben sich für die Ceasar Verschlüsselung entschieden") ; 
	
		else if (auswahl == 50)//50 steht für 2
			printf("sie haben sich für die Vigenere Verschlüsselung entschieden") ;
		 
		else if (auswahl == 51)//51 steht für 3
			printf("sie haben sich für die Symmetrische Verschlüsselung entschieden") ;
	
		else if (auswahl == b)//bzw. 98
			printf("Danke das sie sich für das Programm endschieden haben") ;
	
	}
	
	return 0;
}

es ist zwar nicht grade hübsch vorallem gefallen mir die if auswahlen für 1,2,3 und beenden mit b nicht aber habe keine andere lösung gefunden da ich nicht richtig verstehe wie diese umwandlung funktioniert

Zitat

so wird aber nur der Inhalt von b nach auswahl kopiert, um bei dem Beispiel mit der '1' zu bleiben, steht dann in auswahl die Zahl 49, was aber nicht korrekt ist. Du benötigst also eine andere Lösung, um einen char in einen int umzuwandeln.

vlt kann mir da jemand anhand eines bsp. das näher bringen wäre euch da sehr dankbar :D

Aber ihr habt mir so aufjedenfall schon mal sehr weitergeholfen danke 🤘

Bearbeitet von Pizzacorgie28
Link zu diesem Kommentar
Auf anderen Seiten teilen

Ein char ist intern auch nur ein Zahlenwert, der exakt ein Byte groß ist. Komischer Zufall, wa? ;) Historisch betrachtet ist ein Byte die Menge an Bits, die benötigt werden, um ein Zeichen darzustellen.  Mit Hilfe der ASCII-Tabelle weiß die Grafikkarte nun, wie das Zeichen mit dem Wert 98 aussieht. Es ist nämlich ein b. Der Weg geht auch andersrum. Man kann ein Zeichen in Hochkommata setzen und der Compiler wandelt es zurück in eine Zahl.  Du kannst dann also z.B.

while (auswahl != 'b') {

schreiben und der Compiler macht aus 'b' eine 98. Dasselbe gilt auch für deine if-Abfragen.

Du kannst ja mal folgenden Code testen:

printf("%d", 'b');

Du siehst, als Ergebnis kommt 98 raus.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Das sieht schon nicht schlecht aus, die Aufgabenstellung erfüllt das Programm ja. Aber wie du bereits angemerkt hast, kann man den Code noch etwas leserlicher gestalten. Gestern hattest du in einem Code Ausschnitt noch folgende Zeile:

printf("Bitte eine der oben genannten zeichen eingeben\n");

Die würde ich wieder mit in das Programm aufnehmen, damit der spätere Benutzer des Programms weiß, das seine letzte Eingabe nicht gültig war.

vor einer Stunde schrieb Pizzacorgie28:

vorallem gefallen mir die if auswahlen für 1,2,3 und beenden mit b nicht

Da würde ich dir recht geben, schauen wir uns mal den Fall für 1 an:

if (auswahl == 49) //49 steht für 1

49 steht zwar korrekterweise für das Zeichen '1', aber ohne den Kommentar daneben wäre das für einen anderen Programmierer der deinen Code liest nicht ersichtlich wo die magische 49 herkommt (Außer er hat die ASCII Tabelle auswendig gelernt, aber davon würde ich nicht ausgehen).

Das könnte man dann zwar so lösen:

int  ceaser=49;

if (auswahl == ceaser)
...

Trotzdem ist die 49 noch etwas magisch, da in der Aufgabenstellung steht, das eine 1 erwartet wird. Du könntest jetzt zwar deine eigene Methode schreiben, die chars in den entsprechenden int Wert umwandelt, aber glücklicherweise ist das nicht das erste mal, das jemand so eine Umwandlung vor hat und man muss das Rad nicht neu erfinden. Nachdem ich char to int Umwandlung in einer Suchmaschine eingegeben hab, wurde mir die atoi() Methode vorgeschlagen.

Bearbeitet von JustALurker
typo gefixt
Link zu diesem Kommentar
Auf anderen Seiten teilen

vor 2 Minuten schrieb Whiz-zarD:

Wozu willst du das Zeichen '1' noch in eine 1 umwandeln? Ich sehe hier keinen Bedarf für.

 

Naja ist an sich nicht notwendig da hast du schon recht :D 

aber für den Betrachter des Codes aufjedenfall wie @JustALurker  beschreibt dann schon verständlicher ich werde mich allerdings erst einmal mit den Verschlüsselungs Methoden beschäftigen und mich dann um solche Verschönerungen versuchen da ich grade auch nicht ganz verstehe wie atoi() funktioniert.

Dies wird mit Sicherheit nicht meine letzte frage im Forum sein ;) .

Tausend Dank euch nochmal für eure Hilfe  💝 

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

vor 21 Stunden schrieb JustALurker:

ceaser, vigenere und symmetrische müssen ja nicht zwangsweise Zahlen sein.

Genau das! Zumal man diese Variablen doch sowieso nicht braucht, oder?

@Pizzacorgie28 In der If-Abfrage musst du dann nicht nach Integerwerten fragen sondern kannst direkt nach Char-Werten fragen, indem du den "eigentlichen" Wert in Hochkommata setzt. Eine Wertzuweisung macht für mich am Anfang auch keinen Sinn, außer du würdest dann direkt Abfragen "if ( auswahl == ceaser )" etc. D.h. eigentlich kannst du die drei Variablen auch weglassen und dann jeweils einfach nur fragen "if (auswahl == '1')" usw.

vor 23 Stunden schrieb Pizzacorgie28:

while (auswahl != b )

Müsste die Bedingung von der While-Schleife nicht auch in Hochkommata oder aber als Zahlenwert dort stehen?

Übrigens könntest du statt 4 If-Abfragen auch mit Switch Case arbeiten und dort dann auch, wie ich oben schon geschrieben habe, die Eingabe direkt mit den Variablen, denen du einen Wert zugewiesen hast, vergleichen. Dabei sollten die Variablen aber eher Konstanten sein, da sich der Wert ja nicht ändern soll.

Bearbeitet von Rienne
Link zu diesem Kommentar
Auf anderen Seiten teilen

Finde die Lösung von @Rienne  super das sollte reichen wir wollen es ja nicht gleich übertreiben :D 

aber sagt mal nur noch so als frage nebenbei.

printf("Bitte eine der oben genannten zeichen eingeben\n");

wenn ich den Befehl  vor der Eingabe ausspucke siehe hier:

int main(void){
	//int  ceaser=1, vigenere=2 , symmetrische=3, eingabe=0;
	char b=98, auswahl=0;
	//char beenden=b; b=98 in ascii tabelle 
	
	
	printf("Herzlich Willkommen\n\nWas wollen Sie tun?\n Drücken sie 1-3 für die jeweilige verschlüsselungs variante\n oder b um das Programm zu beenden\n");
	printf(" (1) Ceasar Verschlüsselung\n (2) Vigenere Verschlüsselung\n (3) Symmetrische Verschlüsselung\n (b) Beenden\n\n");
	//auswahl funktion hier
	
	while (auswahl != b){
		printf("\nBitte geben sie eine der oben genannten zeichen ein:\n");
		scanf("%c", &auswahl) ;		
				
		if (auswahl == '1') //49 steht für 1
			printf("sie haben sich für die Ceasar Verschlüsselung entschieden") ; 
			
		
	
		else if (auswahl == '2')//50 steht für 2
			printf("sie haben sich für die Vigenere Verschlüsselung entschieden") ;
			
		
		 
		else if (auswahl == '3')//51 steht für 3
			printf("sie haben sich für die Symmetrische Verschlüsselung entschieden") ;
			
	
		
	
	}
	printf("Danke das sie sich für das Programm endschieden haben") ;
	return 0;
}

habe ich das problem wenn eine falsche zahl eingegeben wird er den

 printf("\nBitte geben sie eine der oben genannten zeichen ein:\n");

text 2 mal auspuckt liegt das am enter oder wo ist das problem? und wie kann ich das umgehen 😅

Link zu diesem Kommentar
Auf anderen Seiten teilen

vor 8 Minuten schrieb Pizzacorgie28:

Dafür hasse ich C das es immer an so Kleinigkeiten hängt.

Das ist nicht nur bei C so, sondern bei sehr vielen Programmiersprachen. Liegt einfach daran, dass darunter nun einmal eine Maschine arbeitet, die konkrete Daten braucht und wenig Raum für Interpretation bietet. D.h. du als Entwickler musst dafür sorgen, dass die möglichen Fehler von Benutzern korrekt abgehandelt werden. (Ich selber entwickle in ABAP und da ist es sogar problematisch, wenn du bei gewissen Klammern kein Leerzeichen setzt ^^')

Daher auch mein Vorschlag statt mit If mit Switch-Case zu arbeiten, da du dort direkt einen Zweig (default) hast, der allen anderen Eingaben als den gewünschten (1,2,3,b) abhandeln kann.

vor 50 Minuten schrieb Pizzacorgie28:

while (auswahl != b)

Die Abfrage solltest du meines Wissens nach trotzdem eher

while (auswahl != 'b')

lauten. Oder ist C da nicht so penibel?

Link zu diesem Kommentar
Auf anderen Seiten teilen

vor 7 Minuten schrieb Rienne:

Oder ist C da nicht so penibel?

Korrekt, das würde so nicht compilen. Der Vergleich mit b impliziert, dass es eine Variable mit dem Namen b gibt, anstatt mit dem char 'b' zu vergleichen. Allerdings hat er ja recht weit oben die Variable char b; deklariert, deswegen ist das kein Problem.

Bearbeitet von blaargh
Link zu diesem Kommentar
Auf anderen Seiten teilen

lese ja eh chars ein dementsprechend ist das dann ja eh b hat bis jetzt ohne ' ' funktioniert.

vor 6 Minuten schrieb Rienne:

(Ich selber entwickle in ABAP und da ist es sogar problematisch, wenn du bei gewissen Klammern kein Leerzeichen setzt ^^')

und das hört sich ja nach spaß an 😂.

An sich finde ich programmieren auch  interessant und spannend und wenn es funktioniert macht es auch spaß. Aber programmieren ist halt auch sehr undankbar wenn man Fehler macht und nicht sehr hilfreich wenn man dann nicht weiter weiß 🤯.

Habe bis jetzt ein wenig mit Python mich probiert fand ich deutlich verständlicher als C.

Link zu diesem Kommentar
Auf anderen Seiten teilen

vor 3 Minuten schrieb blaargh:

Allerdings hat er ja recht weit oben die Variable char b; deklariert, deswegen ist das kein Problem.

Da muss ich mich mal kurz selber korrigieren: Da wurde zwar char b deklariert, allerdings falsch initialisiert. Du initialisierst die Variable da mit sich selbst, ich schätze das ist undefined behaviour. Da willst du auf jeden Fall char b = 'b' schreiben.

Link zu diesem Kommentar
Auf anderen Seiten teilen

vor 9 Minuten schrieb Pizzacorgie28:

lese ja eh chars ein dementsprechend ist das dann ja eh b hat bis jetzt ohne ' ' funktioniert.

Wie @blaargh schon schreibt liegt das daran, dass du auch eine Variable hast, die so heißt. Du solltest das Coding aber einheitlich gestalten. Also entweder fragst du direkt nach Charactern ab, dann muss das bei allen in Anführungszeichen oder aber du fragst auf den Wert der Variablen/Konstanten ab, dann müsstest du aber bei den anderen Abfragen statt '1','2' und '3' mit ceaser, vigenere und symmetrische vergleichen. Durch diese Vermischung ist es (gerade auch für dich selber, wenn ich deine Antwort lese) schwer nachvollziehbar, was das Coding jetzt genau machen soll. 🙂

@blaargh falsch initiiert ist sie nicht, da der Variable b der Integerwert 98 zugewiesen wird, der 'b' entspricht. Nichtsdestotrotz ist es so nicht gerade übersichtlich und man sollte sich vielleicht über die Benennung der Variablen mehr Gedanken machen (gerade wenn es später um wesentlich komplexere Programme geht :D)

Bearbeitet von Rienne
Link zu diesem Kommentar
Auf anderen Seiten teilen

Dein Kommentar

Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...