MULTIMEDIA, Video digital, Grabación, Diseño gráfico, Diseño web, Programación > Webmasters - Diseño Web - Programación - Diseño gráfico

sscanf y sprintf

(1/3) > >>

Jordi Cabré Roca:
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.

ALP:
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: --- sscanf (buffer, "%s;%i;%i", usr->nick, &usr->ip, &usr->port);
--- Fin del código ---


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.

Dabo:
bienvenido jordi

eres un crack ALP  :wink:

Jordi Cabré Roca:
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

ALP:
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: ---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);
}
--- Fin del código ---

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: ---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);
}
--- Fin del código ---

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.

Navegación

[0] Índice de Mensajes

[#] Página Siguiente

Ir a la versión completa