Code:Passworteingabe in einer Win32Console
-
@AJ:
1. Ein char wird bei mir zuerst mit einer Konstante dann mit einer Escapesequenz und nur wenn nicht anders möglich mit einer Zahl initialisiert.
3. Hexadezimale Zahl nur weil in der FAQ und auch in der MSDN 0xE0 steht statt 224. Was ich allerdings nicht weiß warum ich 10 und 13 nicht mit '/r' und '/n' definiert habe - naja seis drum, kann man ja noch ändern ;).
@Dezipiator: VString hat für mich irgendwie keinen Sinn, im Grunde erfindest du nur das Rad neu. Wenn du schon noch ein paar Zusatzfunktionen bieten willst erbe doch von std::string public und füge noch etwas dazu. Aber es gibt schon soviele Stringklassen das eine mehr fast nichts mehr bringt.
Readline klingt schon ganz gut. Ich persönlich will immer noch eine getch-Streamklasse erstellen die für die einzelnen Typen überladen ist. Wenn ich zB getch auf einen Integer anwende kommt das FAQ-Beispiel "Reine Zahleneingabe" zur Geltung. Wenn ich einen char nehme kann man nur Zeichen eingeben (eventl. auch mit einem Flag welche genau also zB A-Za-z0-9() also so eine Art Zeichenklassen wie man sie von den Regex-Funktionen kennt).
VDialog klingt mir ziemlich nach MFC?! Was genau soll da wie gekapselt werden?
MfG SideWinder
-
@Side
Dann hast du da wohl noch einen Fehler in deinem Quellcode. Soll das jetzt 0x0E sein oder 0xE0???
-
ka das kann ich mir nie merken - *auch in die FAQ schau* 0x0E passt schon.
MfG SideWinder
-
VString bietet meist das ,was oft zum Problem wird.
Automatische Typenumwandlung.
Außerdem werden viele Operatoren überladen, die doch das Leben z.b. bei cin und cout sehr vereinfachen :hier die definition:
http://spotlight.de/zforen/cpp/m/cpp-1060116715-15802.htmlVDialog ist eigentlich nur dazu gedacht,
schnell ein Dialog zu erstellen, und auf Nachrichten zu reagieren.
Man muss dazu nicht VDialog überschreiben, sondern ein EventHandler Objekt, dass dann dem Dialog übergeben wird.
Man muss sich nicht mit der Winapi beschäftigen.Außerdem hat das alles einen großen Vorteil :
Es ist klein und kommt ohne jegliche DLLs aus!
-
Ich habe mal ein wenig korrigiert, damit die Fehlermeldungen aufhören und das überhaupt geht. So schluckt das auch der Dev-C++:
#include <iostream> #include <string> #include <conio.h> using namespace std; string read_password ( int maxlength ) { string pw ( "" ); char now ( '\0' ); while ( ( maxlength-- > -1 ) && ( now != 13 ) && ( now != 10 ) ) { // Zeichen einlesen now = getch (); // Bei Sonderzeichen zweites Zeichen ignorieren if ( now == 0 || now == 0xE0 ) // 0xE0 = 224 { getch (); } // Backspace abfangen else if ( now == '\b' ) { pw.erase ( pw.end()-1 ); cout << "\b \b"; maxlength+=2; } // Wenn Zeichen normal dann an das Passwort anhängen if( (now == 13) || (now == 8) ) { } else { pw = pw + now; cout << '*'; } } return ( pw ); } int main() { cout << "Passwort eingeben: "; string pw = read_password(5); if (pw == "Hal?o") cout << "\no.k." << endl; else cout << "\nfalsches Passwort" << endl; getch(); }
Ist aber noch nicht völlig in Ordnung, z.B. Backspaces über Anfang hinaus, kann man aber mit leben.
-
Hallo ! der code is super nur kann man nicht die BACKSPACE taste benützen.. also man kann es schon und er reagiert auch auf dei BACKSPACE taste nur zeig er das nicht an .. er zeigt noch eine gedrückte taste an.
Bsp.:
ich gebe ein abcd[BACKSPACE]
BILDSCHIRM: ***** //er macht noch ein Stern für BACKSPACE statt eins zu löschen
Aber wenn ich das PW ausgebe kommt das richtige raus:
BILDSCHIRM: abckannst du bitte den code noch so verbessern das er ein sternchen löscht statt eins dazu zu machen .... pls.! DANKE!
-
Also meine nachricht war an Dezipaitor und gemeint habe ich den CODE den er ganz am Anfang geschrieben hat!
-
Warum nimmst Du nicht den einfacheren Code?
-
ich finde, bei den vielen passwortfragen könnte dezipaitors code in die faq für konsole mit winapi möglichkeit (windows.h) und für die dos und djgpp leute kann was daneben gestellt werden.
-
So, hier meine Version für ANSI-C
char *read_password(char *password, int maxlength, char passchar) { char *pos=password; char now=0; //Solange die Taste Return nicht gedrückt wurde //und solange die maximale Anzahl an Zeichen nicht erreicht wurde while(now!=13 && now!=10 && pos-password<maxlength) { // Zeichen einlesen now=getch(); // Bei Sondertaste zweites Zeichen ignorieren if(now==0 || now==0xE0) // 0xE0 = 224 { getch(); continue; // Nächstes Zeichen einlesen } else if(now==8) //Wenn Backspace gedrückt wurde { if(pos>password) //Nur wenn schon ein Zeichen da ist! { *--pos=0; //Zuletzt eingegebenes Zeichen löschen printf("\b \b"); //Bildschirmausgabe korrigieren } } // Wenn eingelesenes Zeichen kein Steuerzeichen ist if(now>31) { *pos++=now; //Zeichen speichern putch(passchar); //Passwortzeichen ausgeben } } return(password); //Passwort zurückgeben }
Edit: Schönheitskorrekturen
-
Hey AJ supa cool bitte schreib auch eine main dazu wie man die Fkt. aufruft bitte!!!! -> Bin Anfänger! DANKE!
-
Das Backspace war garnicht vorgesehen.
Deshalb hier die Erweiterte Variante.
Allerdings funktioniert das Backspace nicht über das horizontale Zeilenende hinaus. Sobald der Cursor darüber hinaus geht, kann er nicht mehr zurück (der interne Zeichenpuffer wird trotzdem geändert)
Außerdem wird jetzt nicht mehr abgebrochen, wenn die maximale Anzahl von Zeichen erreicht wurde - in diesem Fall kann man einfach nicht mehr weiterschreiben -> Backspace geht allerdings schonCode
siehe weiter untenSobald ich es mal geschafft habe bei Sourceforge.net einen Account zu eröffnen.
Lade ich die erweiterte Konsolenklasse hoch
-
hi! @Dezipaitor
Du hast am anfang des codes etwas vergessen:HANDLE m_STD_INPUT_HANDLE = GetStdHandle(STD_INPUT_HANDLE); HANDLE m_STD_OUTPUT_HANDLE = GetStdHandle(STD_OUTPUT_HANDLE);
Aber sonst Funktionier alles einwandfrei! echt toll danke man!
-
@elise: Jetzt lass den Thread doch erstmal reifen :p
Standard C++ Variante:
@Erhard Henkes: Niemals Namespaces in eigenen Headern öffnen! Außerdem ist -1 ein Fehler gibt er 0 an wird die Schleife trotzdem einmal ausgeführt!
#include <iostream> #include <string> #include <conio.h> std::string read_pw ( unsigned short int Maxlength , char Ersatz = '*' ) { std::string pw ( "" ); char now ( '\0' ); while ( ( Maxlength-- > 0 ) && ( now != 13 ) && ( now != 10 ) ) { /* Zeichen einlesen */ now = getch (); /* Bei Sonderzeichen zweites Zeichen ignorieren */ if ( now == 0 || now == 0xE0 ) { getch (); } /* Backspace abfangen */ else if ( now == 8 ) { /* Wenn bereits Zeichen im String vorhanden sind */ if ( pw.length () = 0 ) { pw.erase ( pw.end() - 1 ); cout << "\b \b"; Maxlength += 2; } } /* Wenn Zeichen normal dann an das Passwort anhängen */ else if ( now != 13 ) { pw = pw + now; cout << Ersatz; } } return ( pw ); }
So final herausgebracht.
MfG SideWinder
-
habt ihr mal Umlaute getestet?
-
Dezipaitor schrieb:
habt ihr mal Umlaute getestet?
Nein was passiert dann?
MfG SideWinder
-
bei meinem code passiert nix,
solange die CodePage nicht auf Deutsch umgestellt wurde - Allerdings habe ich es noch nicht geschafftwie sieht es bei den anderen aus?
-
Kann sein, dass getch() Probleme macht mit den Umlauten. Das hatte ich auch schon mal bemerkt bei einem anderen Programm. Könnte daran liegen, dass getch() eigentlich nur für 16Bit Anwendungen gedacht ist. Umsonst steht in so manchen Hilfen nicht der Hinweis, dass man getch() nicht in 32Bit Anwendungen einbauen soll.
-
PS: @hobbyprogrammer
int main(void) { char passwort[10]; printf("Bitte Passwort eingeben: "); read_password(passwort, 8, '*'); putch('\n'); if(!strcmp(passwort, "willrein")) { printf("Passwort korrekt."); } else { printf("Falsches Passwort!"); } }
-
Bei Windows-Konsolen ist der Amerikanische Zeichensatz standard.
D.h. das Umlaute (öüä) nicht richtig dargestellt werden.ReadConsoleInput gibt in einem solchen Fall einen Charcode kleiner als 0 zurück (deshalb wird die Eingabe nicht im code angenommen).
Normalerweise kann man den Satz mit SetConsoleCP oder SetConsoleOutputCP umstellen - allerdings habe ich Zahlen zwischen 0 und 100.000 ausprobiert = ohne Erfolg.