Autor Tema: sscanf y sprintf  (Leído 8667 veces)

Desconectado Jordi Cabré Roca

  • Newbie
  • *
  • Mensajes: 3
sscanf y sprintf
« en: 17 de Junio de 2004, 03:33:17 pm »
Buenas a todos/as:
   Escribo ente hilo para preguntaros que pasa en el siguiente trozo de codigo que os envio, dado que hace lo que desearía que hiciese.
   Prmero explico lo que quiero hacer. He creado una estructura de datos en C de la siguiente forma:
      typdef struct user {
           char nick [NICK_LENGTH];
           int ip;
           int port;
       }tuser;
y he implementado dos funciones, que sirven para serializar esta estructura y deserializarla.
   void user_serialize (struct user *usr, char *buffer) {
       sprintf (buffer, "%s;%i,%i", usr->nick, usr->ip, usr->port);
    }
    void user_unserialize (struct user *usr, char *buffer) {
       sscanf (buffer, "%s;%i;%i", usr->nick, usr->ip, usr->port);
    }
Despues de haber ejecutado el siguiente codigo no me sale lo que se debe:
   ...
   user_serialize (usr1, buffer);
   user_unserialize (usr2, buffer);
   ...
   -->>>>>>>>> usr1 no tiene el mismo nick, solo sale un trozo, el campo ip es diferente y el campo puerto tambien.

A que puede ser debido?

Gracias de antemano.

Desconectado ALP

  • Member
  • ***
  • Mensajes: 234
sscanf y sprintf
« Respuesta #1 en: 17 de Junio de 2004, 11:43:18 pm »
Las cadenas de sprintf() y sscanf() son diferentes. En la sscanf() hay dos punto y coma, y en la otra hay un punto y coma y una coma como separadores.

Por otro lado, a sscanf() debes pasar punteros, el nick por sí mismo ya lo es, pero los otros dos no. La línea debería ser así:
Código: [Seleccionar]
sscanf (buffer, "%s;%i;%i", usr->nick, &usr->ip, &usr->port);

Para finalizar, asegúrate de que el campo nick de la estructura que pasas a user_unserialize() debe estar relleno con ceros. Lo puedes hacer con las funciones memset(), setmem(), strset(), o un bucle. Si estás desarrollando en linux, también dispones de bzero().

Un saludo.
Si no puedes deslumbrar con tu sabiduría, desconcierta con tus gilipolleces.

Desconectado Dabo

  • Administrator
  • *
  • Mensajes: 15348
    • https://www.daboblog.com
sscanf y sprintf
« Respuesta #2 en: 18 de Junio de 2004, 04:53:21 pm »
bienvenido jordi

eres un crack ALP  :wink:
Hacking, computing, are in my blood, are a part of me, a part of my life...Debian GNU/Linux rules.

Twitter; https://twitter.com/daboblog
Instagram: @daboblog


www.daboblog.com | www.debianhackers.net | www.caborian.com | www.apachectl.com | www.davidhernandez

Desconectado Jordi Cabré Roca

  • Newbie
  • *
  • Mensajes: 3
sscanf y sprintf
« Respuesta #3 en: 19 de Junio de 2004, 05:20:08 pm »
Bueno, lo del punto y coma , ha sido un inorputo despiste a la hora de escribir el hilo. Por lo que hace a los punteros, ya lo he canviado y igialmente no hace lo que desearía que hiciese, no se, alguna sugerencia más?

Gracias

Desconectado ALP

  • Member
  • ***
  • Mensajes: 234
sscanf y sprintf
« Respuesta #4 en: 20 de Junio de 2004, 02:10:49 pm »
Hola de nuevo....he estado indagando algo, ya que hace tiempo que no trabajaba con sscanf().

Según el libro de K&R, en las funciones de la familia scanf(), "Un campo de entrada está definido como una cadena de caracteres que no son espacios en blanco;" (un "campo de entrada" es una secuencia del tipo %s, %i, etc).

Pues bien, si cambiamos los caracteres punto y coma que has puesto como separadores por espacios en blanco, funciona perfectamente. Entendemos por espacios en blanco los espacios, nueva línea, tabulador, retorno de carro, etc. Por ejemplo:

Código: [Seleccionar]
void user_serialize (struct user *usr, char *buffer) {
    sprintf (buffer, "%s\n%i\n%i", usr->nick, usr->ip, usr->port);
}

void user_unserialize (struct user *usr, char *buffer) {
    sscanf (buffer, "%s\n%i\n%i", usr->nick, &usr->ip, &usr->port);
}

El problema lo encontramos si dentro del nick hay un espacio en blanco, ya que scanf detendrá la lectura del primer campo (el nick) cuando encuentre un espacio en blanco. Hay muchas soluciones a este problema. Una de ellas podría ser:
Código: [Seleccionar]
void user_unserialize (struct user *usr, char *buffer) {
    char *ptr;

    ptr = strchr(buffer, '\n');
    strncpy(usr->nick, buffer, ptr-buffer);
    sscanf (ptr+1, "%i\n%i", &usr->ip, &usr->port);
}

Lo que hacemos es buscar el primer '\n', y copiamos en el campo nick los caracteres que van desde el comienzo hasta el  '\n' (sin incluirlo). Luego, tratamos el buffer con sscanf(), desde la posición siguiente al primer '\n'.

Espero que esto solucione tu problema.

un saludo.
Si no puedes deslumbrar con tu sabiduría, desconcierta con tus gilipolleces.

Desconectado Jordi Cabré Roca

  • Newbie
  • *
  • Mensajes: 3
sscanf y sprintf
« Respuesta #5 en: 21 de Junio de 2004, 03:46:31 pm »
Gracias por tus molestias.

Desconectado ALP

  • Member
  • ***
  • Mensajes: 234
sscanf y sprintf
« Respuesta #6 en: 22 de Junio de 2004, 12:56:42 am »
No es molestia. A mandar... que pa' eso estamos.

un saludo.
Si no puedes deslumbrar con tu sabiduría, desconcierta con tus gilipolleces.

Desconectado jirho

  • Member
  • ***
  • Mensajes: 303
sscanf y sprintf
« Respuesta #7 en: 23 de Junio de 2004, 10:39:57 pm »
...uff...si ya casi que ni me toca entrar...gracias ALP...un saludo amigo...
[root@local_host jirho]#Conecting to underground zone...:superman:

http://www.hackeando.com/gifs/logomini.gif

Desconectado ALP

  • Member
  • ***
  • Mensajes: 234
sscanf y sprintf
« Respuesta #8 en: 24 de Junio de 2004, 02:48:28 am »
jirho...te subestimas...
Si no puedes deslumbrar con tu sabiduría, desconcierta con tus gilipolleces.

Desconectado jirho

  • Member
  • ***
  • Mensajes: 303
sscanf y sprintf
« Respuesta #9 en: 23 de Julio de 2004, 10:07:57 pm »
...solo aprecio lo que haces ALP... :wink: ...
[root@local_host jirho]#Conecting to underground zone...:superman:

http://www.hackeando.com/gifs/logomini.gif

 

Aviso Legal | Política de Privacidad | Política de Cookies

el contenido de la web se rige bajo licencia
Creative Commons License