Strcat lanza error de segmentación en getch sencilla como introducción de la contraseña

StackOverflow https://stackoverflow.com/questions/4093847

  •  28-09-2019
  •  | 
  •  

Pregunta

Estoy utilizando Linux y hay una función personalizada de los cuales devuelve un int ASCII de la corriente de clave de ordenación como getch(). Al tratar de acostumbrarse a ella y la forma de almacenar la contraseña entré en un problema, mi código es el siguiente:

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;
}

Por desgracia consigo la advertencia del 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’

He intentado utilizar punteros en lugar de una matriz de caracteres para el pase, pero el segundo tipo I una carta que segfaults. La función es eficaz por sí solo, pero no en el bucle, al menos no como getch () lo haría en un sistema Windows.

¿Qué se puede ver que está mal con mi ejemplo? Estoy disfrutando el aprendizaje de esta.

EDIT: Gracias a las respuestas que dieron con el siguiente código de tonto:

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);
¿Fue útil?

Solución

El problema es que strcat espera una char * como segundo argumento (que concatena dos cadenas). No tiene dos cadenas, que tiene una cadena y uno char.

Si desea agregar c hasta el final de pass, sólo mantener un i int que almacena el tamaño actual de pass y luego hacer algo como

pass[i] = (char) c.

Asegúrese de nulo por terminado pass cuando haya terminado (mediante el establecimiento de la última posición a 0).

Otros consejos

Un único personaje no es lo mismo que una cadena que contiene un único carácter.

En otras palabras, 'a' y "a" son cosas muy distintas.

Una cadena, en C, es una matriz terminada en nulo de caracteres. Su "pase" es una matriz de 20 caracteres -. Un bloque de memoria que contiene espacio para 20 caracteres

El mygetch función () devuelve un char.

Lo que hay que hacer es insertar c en uno de los espacios.

En lugar de "strcat (pase, c)", que quiere hacer "pase [i] = c", donde i comienza en cero, y se incrementa en uno por cada vez que llame mygetch ().

A continuación, lo que necesita hacer un pase [i] = '\ 0', cuando se realiza el bucle, con i igual al número de veces que ha llamado mygetch (), añadir el terminador nulo.

Usted es otro problema es que no se ha establecido un valor de c, la primera vez que revise a ver si es '\ n'. Al que desea llamar mygetch () antes de hacer la comparación:

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

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

Más allá de la cuestión diagnosticados correctamente con strcat() de dos cadenas - ¿por qué hacer caso omiso de las advertencias del compilador, o si no hubo advertencias, ¿por qué no tener advertencias encendidos? A lo que iba, más allá de ese problema, también es necesario tener en cuenta lo que sucede si usted consigue EOF, y también hay que preocuparse por el valor inicial de 'c' (que podría ser accidental '\ n' aunque probablemente ISN 't).

que conduce a código como este:

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

Me pasó de 'mygetch ()' a 'getchar ()' - sobre todo porque lo que digo se aplica a eso y podría no aplicarse a su 'mygetch ()' función; no tenemos una especificación de lo que hace la función de un EOF.

Por otra parte, si debe utilizar strcat(), todavía se necesita para mantener un seguimiento de la longitud de la cadena, pero se puede hacer:

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++;
}

No es tan elegante como todo lo que - usando strcat() en su contexto es un exceso. Se podría, supongo, hacer el recuento simple y repetida utilización strcat(pass, c), pero que tiene un comportamiento cuadrática como strcat() tiene que saltar de 0, 1, 2, 3, ... caracteres en las siguientes iteraciones. Por el contrario, la solución en la que apunta a la DST NUL al final de los medios de cadena que strcat() todavía no tiene nada para saltar. Con una adición de tamaño fijo de 1 carácter, sin embargo, usted es probablemente mejor con el primer bucle.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top