Frage

Ich verwende Linux und es gibt eine benutzerdefinierte Funktion von der gibt eine ASCII int von aktueller Schlüssel Art wie getch(). Beim Versuch, sich daran zu gewöhnen und wie das Passwort speichern ich in ein Problem kam, mein Code ist wie folgt:

int main() {
    int c;
    char pass[20] = "";

    printf("Enter password: ");
    while(c != (int)'\n') {
        c = mygetch();
        strcat(pass, (char)c);
        printf("*");
    }

    printf("\nPass: %s\n", pass);

    return 0;
}

Leider bekomme ich die Warnung von GCC:

pass.c:26: warning: passing argument 2 of ‘strcat’ makes pointer from integer without a cast
/usr/include/string.h:136: note: expected ‘const char * __restrict__’ but argument is of type ‘char’

habe ich versucht, Zeiger anstelle eines char-Array für Pass verwenden, aber der zweite Typ I einen Brief es Segfaults. Die Funktion arbeitet auf seinem eigenen, aber nicht in der Schleife, atleast nicht wie getch () würde auf einem Windows-System.

Was können Sie sehen, ist falsch mit meinem Beispiel? Ich genieße das Lernen.

EDIT: Dank der Antworten kam ich mit dem folgenden dummen Code auf:

int c;
int i = 0;
char pass[PASS_SIZE] = "";

printf("Enter password: ");
while(c != LINEFEED && strlen(pass) != (PASS_SIZE - 1)) {
    c = mygetch();
    if(c == BACKSPACE) {
        //ensure cannot backspace past prompt
        if(i != 0) {
            //simulate backspace by replacing with space
            printf("\b \b");
            //get rid of last character
            pass[i-1] = 0; i--;
        }
    } else {
        //passed a character
        pass[i] = (char)c; i++;
        printf("*");
    }
}
pass[i] = '\0';
printf("\nPass: %s\n", pass);
War es hilfreich?

Lösung

Das Problem ist, dass strcat eine char * als zweites Argument erwartet (es werden zwei Strings verkettet). Sie haben noch zwei Strings, Sie haben einen String und ein char.

Wenn Sie c bis Ende pass hinzufügen möchten, halten nur einen int i, dass die aktuelle Größe von pass speichert und dann wie etwas tun

pass[i] = (char) c.

Stellen Sie sicher, auf Null beenden pass, wenn Sie (indem Sie die letzte Position auf 0) durchgeführt werden.

Andere Tipps

Ein einzelne Zeichen ist nicht das gleiche wie eine Zeichenfolge ein einzelnes Zeichen enthält.

Mit anderen Worten, 'a' und "a" sind sehr verschiedene Dinge.

Ein String, in C, ist ein Null-terminierte Array von Zeichen. Ihr „Pass“ ist ein Array von 20 Zeichen -. Ein Speicherblock enthält Platz für 20 Zeichen

Die Funktion mygetch () gibt ein Zeichen.

Was Sie tun müssen, ist c in einem der Räume einzufügen.

Anstelle von "strcat (Pass, c)", wollen Sie tun "pass [i] = c", wobei i beginnt bei Null, und erhöht durch eine für jedes Mal, wenn Sie mygetch () aufrufen.

Dann brauchen Sie einen Pass tun [i] = ‚\ 0‘, wenn die Schleife durchgeführt wird, mit i auf die Anzahl von Malen gleich Sie mygetch () aufgerufen, den Nullabschluss hinzuzufügen.

Sie sind ein anderes Problem ist, dass Sie keinen Wert für c gesetzt haben, das erste Mal, wenn Sie überprüfen, um zu sehen, ob es die ‚\ n‘. Sie wollen mygetch () aufrufen, bevor Sie tun den Vergleich:

int i = 0;
for (;;)
{
    c = mygetch();
    if (c == '\n')
        break;

    c = mygetch();
    pass[i++] = c;
}
pass[i] = '\0';

Über die richtig diagnostiziert Problem mit strcat() zwei Strings nehmen - warum ignorieren Sie die Compiler-Warnungen, oder wenn es keine Warnungen waren, warum Sie nicht haben Warnungen eingeschaltet? Wie ich sagen war, die über dieses Problem, müssen Sie auch überlegen, was passiert, wenn Sie EOF, und Sie müssen auch Sorge um den Anfangswert von ‚c‘ geschieht (die zufällig ‚\ n‘, obwohl es wahrscheinlich isn sein könnte ‚t).

Das führt zu Code wie folgt:

int  c;
char pass[20] = "";
char *end = pass + sizeof(pass) - 1;
char *dst = pass;

while ((c = getchar()) != EOF && c != '\n' && dst < end)
    *dst++ = c;
*dst = '\0';  // Ensure null termination

I aus ‚geschaltet mygetch ()‘ in ‚getchar ()‘ - vor allem weil das, was ich sage, dass gilt und möglicherweise nicht zu Ihrem ‚mygetch ()‘ Funktion anzuwenden; Wir haben keine Beschreibung dessen, was die Funktion tut auf EOF.

Wenn Sie alternativ strcat() verwenden müssen, müssen Sie noch eine Spur auf der Länge der Saite zu halten, aber Sie tun können:

char c[2] = "";
char pass[20] = "";
char *end = pass + sizeof(pass) - 1;
char *dst = pass;

while (c[0] !=  '\n' && dst < end)
{
    c[0] = mygetch();
    strcat(dst, c);
    dst++;
}

Nicht so elegant wie das alles - strcat() in Zusammenhang mit ist übertrieben. Sie könnten, nehme ich an, tun einfaches Zählen und Verwendung strcat(pass, c) wiederholt, aber das hat quadratische Verhalten als strcat() von 0, überspringen hat 1, 2, 3, ... Zeichen auf den nachfolgenden Iterationen. Im Gegensatz dazu, wo die Lösung dst verweist auf die NUL am Ende der Zeichenfolge bedeutet, dass strcat() nichts zu überspringen hat. Mit einer festen Größe Zugabe von 1 Zeichen, obwohl, sind Sie wahrscheinlich mit der ersten Schleife besser.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top