putch() Fehler beim Einlesen?


  • Mod

    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]).
    Bei strcat 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


Anmelden zum Antworten