Foros de daboweb

MULTIMEDIA, Video digital, Grabación, Diseño gráfico, Diseño web, Programación => Webmasters - Diseño Web - Programación - Diseño gráfico => Mensaje iniciado por: Jordi Cabré Roca en 17 de Junio de 2004, 03:33:17 pm

Título: sscanf y sprintf
Publicado por: Jordi Cabré Roca 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.
Título: sscanf y sprintf
Publicado por: ALP 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.
Título: sscanf y sprintf
Publicado por: Dabo en 18 de Junio de 2004, 04:53:21 pm
bienvenido jordi

eres un crack ALP  :wink:
Título: sscanf y sprintf
Publicado por: Jordi Cabré Roca 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
Título: sscanf y sprintf
Publicado por: ALP 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.
Título: sscanf y sprintf
Publicado por: Jordi Cabré Roca en 21 de Junio de 2004, 03:46:31 pm
Gracias por tus molestias.
Título: sscanf y sprintf
Publicado por: ALP en 22 de Junio de 2004, 12:56:42 am
No es molestia. A mandar... que pa' eso estamos.

un saludo.
Título: sscanf y sprintf
Publicado por: jirho en 23 de Junio de 2004, 10:39:57 pm
...uff...si ya casi que ni me toca entrar...gracias ALP...un saludo amigo...
Título: sscanf y sprintf
Publicado por: ALP en 24 de Junio de 2004, 02:48:28 am
jirho...te subestimas...
Título: sscanf y sprintf
Publicado por: jirho en 23 de Julio de 2004, 10:07:57 pm
...solo aprecio lo que haces ALP... :wink: ...
Título: sscanf y sprintf
Publicado por: ALP en 23 de Julio de 2004, 10:11:46 pm
Güenas....
hacía tiempo que no te leía por aquí.... :D
Título: sscanf y sprintf
Publicado por: jirho en 23 de Julio de 2004, 10:41:56 pm
... :oops: ...bueno, pues si amigo, pero ya llegue y dispuesto a trabajar mucho..un saludo ALP... :wink: ...