putch() Fehler beim Einlesen?
-
völlig ungetestet, weil ich kein getch() habe.
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <conio.h>//hab ich nicht int main() { char passwort[] = "hallo"; char e_passwort[30]; int e_anzahl=0;//fand ich netter als x printf("Passwortabfrage: "); for(;;){ char zeichen=getch(); if(zeichen==0x0d) break; else if(zeichen==0x08){ if(e_anzahl>0){ --e_anzahl; putch(0x08); putch(' '); putch(0x08); } } else{ //edit: ups, vergessen if(e_anzahl<sizeof(e_passwort+-of_by_one_error)) putch('*'); e_passwort[e_anzahl]=zeichen; ++e_anzahl; } } e_passwort[e_anzahl]='\0';//wichtig, die stringfunktionen erwarten nullterminierte strings printf("\n"); printf("e_passwort: %s\n",e_passwort); if(strcmp(e_passwort,passwort)==0)//so vergleicht man strings { printf("\nZugang gewaehrt...\n"); } else //Ansonsten... { printf("\nFalsches Passwort!\n"); } return 0; //Rückgabe 0 }
-
Bin kein hauptberuflicher EDV'ler. Ich bin noch ein Greenhorn.
sizeof() = sagt mir die Größe der Variable in Bytes
strlen() = Die Anzahl der Zeichen ohne \0Stimmt ich hab die Beiden verwechselt.
Ich hab die "\0" jetzt eingefügt. Der Passwortvergleich funktioniert nun danke.Allerdings muss ich noch die Korrekturfunktion richten.
MfG
Edit: Hab nochmal mein Übungsbuch aufgeschlagen, konnte den Konflikt endlich beheben
Übung macht den Meister.
#include <stdio.h> #include <string.h> #include <stdlib.h> int main() { char zeichen; char passwort[] = "hallo", e_passwort[30]; //Deklaration Soll-Passwort und Ist-Passwort. int x=0; //Deklaration für die Anzahl der Arrays in e_passwort[] z.B. e_passwort[x]. printf("Passwortabfrage: "); //Menueueberschrift. zeichen = getch(); //Zeicheneingabe. while(zeichen != '\r') //wenn Zeichen ungleich "Enter". { if(zeichen != '\b') //wenn Zeichen ungleich "Backspace". { e_passwort[x] = zeichen; putch('*'); //Die Zeichen als "*" auf dem Bildschirm ausgeben. x++; } else if((zeichen == '\b') && (strlen(e_passwort) > 0)) //Wenn Zeichen genau gleich "Backspace" und Die Länge des String größer 0 ist. { e_passwort[x-1] = '\0'; putch('\b'); putch(' '); putch('\b'); x--; } zeichen = getch(); } e_passwort[x] = '\0'; if(strcmp(e_passwort, passwort) == 0 && (strlen(e_passwort) <= 5)) //wenn das Eingegebene Passwort genau gleich Soll-Passwort, dann... { printf("\nZugang gewaehrt...\n"); } else //Ansonsten... { printf("\nFalsches Passwort!\n"); } system("pause"); //Programm Pause. return 0; //Rückgabe 0. }
-
strlen
ist ein Stringfunktion. Die braucht einen nullterminierten String, damit sie richtig funktioniert.In deiner
while
-Schleife hast du das aber gar nicht.Allerdings hast du mit x ja schon die Anzahl der Zeichen.
Das
e_passwort[x - 2];
hat übrigens keinen Effekt.
-
Die "Binäre 0" ist jetzt in der Schleife gesetzt. Das Löschen und das Vergleichen funktioniert nun endlich.
MfG
-
Artem90 schrieb:
"Binäre 0"
Deine Vorstellungen über Zahlen im Computer ist ein bisschen komisch.
-
Das wichtigste zuerst:
Du überprüfst nirgends die Länge der Eingabe.
Der Nutzer könnte beliebig lange Passwörter eingeben.
Könnte, weil vorher sicher das Programm/System abstürzt.Beide
strlen
in deinem Code sind überflüssig.In der Schleife kennst du die Länge durch x und ein String ist genau dann gleich, wenn auch die Länge übereinstimmt.( "hallo" und "hallo!" sind unterschiedlich).
Bei der Schleife bietet sich auch ein
do-while
an.
-
Ich hab jetzt den Quelltext etwas geändert, ich hoffe das ich den Pointer richtig gesetzt habe. Die Variable "x" hab ich komplett entfernt und das ganze in eine Schleife verpackt.
Der Compiler bringt nur folgende Warnung: "comparison between pointer und integer [enabled by default]". Das Programm funktioniert aber.
Deine Vorstellungen über Zahlen im Computer ist ein bisschen komisch.
\0 = Nullbyte und
\0 = Binäre 0 laut dem Buch "C programmieren von Anfang an von Helmut Erlenkötter".MfG
#include <stdio.h> #include <string.h> #include <stdlib.h> int main() { char passwort[13] = "hallo"; //Passwort. char *zeichen; //Pointer auf zeichen. char e_passwort[13]; //Passworteingabe. int versuche = 1; printf("Passwortabfrage:\n"); printf("\nSie haben 3 Versuche (max. 12 Zeichen).\n"); while(strcmp(e_passwort, passwort) != 0 && versuche <= 3) //Schleife für 3 Versuche. { printf("\n%i.) Versuch: ", versuche); e_passwort[0] = '\0'; zeichen = getch(); while(zeichen != '\r') { if(zeichen != '\b' && strlen(e_passwort) <= 11) //Wenn zeichen ungleich "Backspace" und Zeichenlänge größer oder gleich 11, dann... { strcat(e_passwort, &zeichen); //Eingegebenes Zeichen an das e_passwort hinten anhängen. printf("*"); } else if(zeichen == '\b' && strlen(e_passwort) > 0) //Wenn zeichen genau gleich "Backspace" und Zeichenlänge größer 0, dann... { e_passwort[strlen(e_passwort) - 1] = '\0'; //"Nullbyte" um 1 zurück verschieben. printf(" \b\b \b"); } else if(strlen(e_passwort) > 12) //Wenn Zeichenlänge größer als 11, dann... { e_passwort[strlen(e_passwort) - 1] = '\0'; //"Nullbyte" um 1 zurück verschieben. printf("\b*\b"); } zeichen = getch(); } versuche++; //Versuche +1. } if(strcmp(e_passwort, passwort) == 0) //Wenn das Passwort genau gleich ist wie das eingegebene Passwort, dann... { printf("\nZugang gewaehrt...\n"); } else //Ansonsten... { printf("\nFalsches Passwort!\n"); } system("pause"); return 0; }
-
Weswegen ist
zeichen
ein Zeiger?
-
Weswegen ist zeichen ein Zeiger?
Wenn ich den Zeiger nicht mache, dann stürzt das Programm ab.
also wenn
char zeichen;
strcat(e_passwort, zeichen); dann kommt ein Programmabsturz.und
char zeichen;
strcat(e_passwort, &zeichen); dann fügt strcat() nach jedem Eintippen ein "hallo" dahinter, also das eigentliche PW (was unter der Variable char passwort[] gespeichert ist).bei
*char zeichen;
strcat(e_passwort, &zeichen); funktioniert das Ganze.Irgendetwas hab ich übersehen, denn Folgendes funktioniert auch:
#include <stdio.h> #include <string.h> #include <stdlib.h> int main() { char zeichen; char text[20]; text[0] = '\0'; zeichen = getch(); while(zeichen != '\r' && (strlen(text) <= 18)) { strcat(text, &zeichen); printf("*"); zeichen = getch(); } printf("\n%s",text); }
-
Artem90 schrieb:
Weswegen ist zeichen ein Zeiger?
Wenn ich den Zeiger nicht mache, dann stürzt das Programm ab.
Mal wieder ein Beweis, dass Compiler-Warnings und -Fehler nie beachtet werden, sondern einfach die Fehler durch wahlloses hinzufügen von Sternen und Ampersand unterdrückt werden, auch wenn sie komplett das Verhalten verändern.
Artem90 schrieb:
char zeichen;
strcat(e_passwort, zeichen); dann kommt ein Programmabsturz.Ja, weil strcat nur C-Strings (also char*) miteinander verknüpfen kann, nicht einzelne Chars. strcat ist also die falsche Funktion für dein Vorhaben. Aber du ignorierst den Compiler, der dir das sagt, und fügst einfach wild Zeichen ein, um das Programm in einen kompilierfähigen, aber falschen Zustand zu bringen.
-
strcat
erwartet zwei Zeiger auf nullterminierte Zeichenketten (sog. C-Strings).Das zweite Argument erfüllt diese Bedingung aber nur durch Zufall. (die Nullterminierung fehlt)
Du kannst zeichen als Array definieren
char zeichen[2] = {'\0', '\0'};
Wenn du dann das Zeichen haben willst (beim getch und beim Vergleich), nimmst du das erste Element (zeichen[0]).
Beistrcat
das ganze Array (zeichen)
Das ist aber nicht C-Style.Noch was:
DirkB schrieb:
Du überprüfst nirgends die Länge der Eingabe.
Der Nutzer könnte beliebig lange Passwörter eingeben.
Könnte, weil vorher sicher das Programm/System abstürzt.Bei der (inneren) Schleife bietet sich auch ein
do-while
an.
-
Zum Anhängen eines einzelnen Zeichens an einen String verwendet man strncat
enum{PSIZE=20}; int main() { char zeichen; char text[PSIZE+1]=""; int i; for(i=0;i<PSIZE&&(zeichen=getch(),zeichen!='\r');++i) strncat(text, &zeichen, 1), printf("*"); printf("\n%s",text); return 0; }
oder direkt beschreiben ohne strncat
int main() { char zeichen; char text[PSIZE+1]=""; int i; for(i=0;i<PSIZE&&(text[i]=getch(),text[i]!='\r');++i) printf("*"); printf("\n%s",strtok(text,"\r")); return 0; }
-
Danke für die Hilfe, die Funktionen sind mir noch nicht bekannt. Ich werde mich erstmal mit dem gepestetem Code befassen, um diesen erstmal zu verstehen.
MfG
-
Artem90 schrieb:
..., die Funktionen sind mir noch nicht bekannt.
So viele Funktionen hat die C-Standardlibrary nun auch nicht, dass man da nicht mal durschauen kann: http://en.cppreference.com/w/c
Besonders nicht bei den Strings: http://en.cppreference.com/w/c/string/byte