Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: MrDev en 12 Abril 2016, 20:41 pm



Título: Problema con rand()
Publicado por: MrDev en 12 Abril 2016, 20:41 pm
Pues tengo un problema, y es que no me da los valores como numeros, me los da como direcciones de memoria supongo que son. Igualmente al poner en el main al principio "in t p=rand();" me daba un 0 todo el rato, aqui dejo el codigo a ver si me podeis echar una manilla.

Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <time.h>
  4.  
  5. char* crearPassword();
  6.  
  7. int main(int argc, const char * argv[]) {
  8.    srand (time(NULL));
  9.  
  10.    float p=rand();
  11.  
  12.    char* contrasena=crearPassword();
  13.  
  14.    printf("%s",contrasena);
  15.  
  16.    return 0;
  17. }
  18.  
  19. char* crearPassword(){
  20.    int i;
  21.    char numero,aleatorio;
  22.    char *password=malloc(8*sizeof(char))+1;
  23.  
  24.    for(i=0;i<4;i++){
  25.        password[i]=(int)rand()%10;
  26.    }
  27.  
  28.    for(i=4;i<8;i++){
  29.        do{
  30.            aleatorio=(char)rand()%123;
  31.        }while(aleatorio<65 && aleatorio>122);
  32.        password[i]=aleatorio;
  33.    }
  34.  
  35.    return password;
  36. }


Título: Re: Problema con rand()
Publicado por: class_OpenGL en 12 Abril 2016, 22:41 pm
Código
  1. do{
  2.    aleatorio=(char)rand()%123;
  3. }while(aleatorio<65 && aleatorio>122);

A ver una cosilla. El número aleatorio está entre 0 y 122, por lo que nunca va a ser mayor que 122. Lo que tendrías que hacer es calcular un número aleatorio entre 0 y la diferencia de 122 y 65, y luego sumarle 65 (aleatorio = (char)rand()%(122-65) + 65;).

También tienes que tener en cuenta que tienes que cambiar la semilla del generador de números aleatorios (rand()) con la función srand cada vez que generes un número aleatorio. Te aconsejo que uses srand(clock()).


Título: Re: Problema con rand()
Publicado por: MrDev en 12 Abril 2016, 22:48 pm
Código
  1. do{
  2.    aleatorio=(char)rand()%123;
  3. }while(aleatorio<65 && aleatorio>122);

A ver una cosilla. El número aleatorio está entre 0 y 122, por lo que nunca va a ser mayor que 122. Lo que tendrías que hacer es calcular un número aleatorio entre 0 y la diferencia de 122 y 65, y luego sumarle 65 (aleatorio = (char)rand()%(122-65) + 65;).

También tienes que tener en cuenta que tienes que cambiar la semilla del generador de números aleatorios (rand()) con la función srand cada vez que generes un número aleatorio. Te aconsejo que uses srand(clock()).

Gracias por la respuesta compi.

Edito, el problema es que en el primer bucle for de la funcion, no guarda en password los numeros :(


Título: Re: Problema con rand()
Publicado por: MAFUS en 12 Abril 2016, 23:20 pm
Código
  1. char *password=malloc(8*sizeof(char))+1;
Esto está mal. malloc te asigna una zona de memoria pero devuelves la posición 1 byte superior. Tal vez quisiste decir:
Código
  1. char *password=malloc((8+1)*sizeof(char));
para guardar la cadena más el caracter nulo.
Pero tampoco convence ya que rand podría generarte un 0 cuándo estás consiguiendo los números, con lo que la cadena resultante acabaría en ese momento. Por otra parte no estás escribiendo caracteres numéricos sino caracteres de control ASCII no imprimibles, por lo que a la hora de visualizar la cadena podrían aparecer efectos extraños en pantalla.
Tal vez quisiste decir:
Código
  1. for(i=0;i<4;i++)
  2.    password[i]=(int)rand()%10+'0';
;

Más. Si usas malloc para asignar memoria debes usar free para liberarla en cuanto no la uses. La penúltima instrucción de tu programa debería ser
Código
  1. free(contrasena);


Título: Re: Problema con rand()
Publicado por: MrDev en 12 Abril 2016, 23:26 pm
Código
  1. char *password=malloc(8*sizeof(char))+1;
Esto está mal. malloc te asigna una zona de memoria pero devuelves la posición 1 byte superior. Tal vez quisiste decir:
Código
  1. char *password=malloc((8+1)*sizeof(char));
para guardar la cadena más el caracter nulo.
Pero tampoco convence ya que rand podría generarte un 0 cuándo estás consiguiendo los números, con lo que la cadena resultante acabaría en ese momento. Por otra parte no estás escribiendo caracteres numéricos sino caracteres de control ASCII no imprimibles, por lo que a la hora de visualizar la cadena podrían aparecer efectos extraños en pantalla.
Tal vez quisiste decir:
Código
  1. for(i=0;i<4;i++)
  2.    password[i]=(int)rand()%10+'0';
;

Más. Si usas malloc para asignar memoria debes usar free para liberarla en cuanto no la uses. La penúltima instrucción de tu programa debería ser
Código
  1. free(contrasena);

Gracias por tu respuesta compi, ya esta el programa listo.

Una duda, en el
Código
  1. for(i=0;i<4;i++)
  2.    password[i]=(int)rand()%10+'0';
;

Por que no funciona sin el "'+0'"?


Título: Re: Problema con rand()
Publicado por: MAFUS en 12 Abril 2016, 23:37 pm
El hecho es que tu generas un carácter del ASCII 0 al ASCII 9, que son caracteres no imprimibles. Busca una tabla en internet de código ASCII y verás lo que digo. Pero al sumar '0' al resultado del rand lo que haces es llevar ese resultado al caracter ASCII '0' que ese sí ya es la representación del cero. ASCII dice que los caracteres numéricos van del cero hasta el nueve. Por tanto '0' + 0 es '0', '0' + 1 es '1', '0' + 2 es '2', etc.
Si te fijas lo mismo pasa con las letras: 'a' + 0 es 'a', 'a' + 1 es 'b'... 'A' + 0 es 'A', 'A' + 1 es 'B'...


Título: Re: Problema con rand()
Publicado por: MrDev en 12 Abril 2016, 23:42 pm
El hecho es que tu generas un carácter del ASCII 0 al ASCII 9, que son caracteres no imprimibles. Busca una tabla en internet de código ASCII y verás lo que digo. Pero al sumar '0' al resultado del rand lo que haces es llevar ese resultado al caracter ASCII '0' que ese sí ya es la representación del cero. ASCII dice que los caracteres numéricos van del cero hasta el nueve. Por tanto '0' + 0 es '0', '0' + 1 es '1', '0' + 2 es '2', etc.
Si te fijas lo mismo pasa con las letras: 'a' + 0 es 'a', 'a' + 1 es 'b'... 'A' + 0 es 'A', 'A' + 1 es 'B'...

Gracias, ya lo entiendo, se aprende bastante en foros :)