Autor Tema: Error al comparar dos strings con strcmp  (Leído 42619 veces)

0 Usuarios y 4 Visitantes están viendo este tema.

Desconectado edu1989

  • PIC18
  • ****
  • Mensajes: 275
Error al comparar dos strings con strcmp
« en: 12 de Enero de 2011, 08:02:26 »
Hola a todos, estoy haciendo una funcion que envia un comando at por el puerto serie y tiene que recibir un OK. Hay que  comparar lo que se recibe por el puerto serie con un "OK" Lo he hecho de la forma:

Código: [Seleccionar]
//Primer comando AT
putst ("AT/n");


 if (getch_available() == true) //Comprueba si hay un caracter disponible recibido por el puerto serie
 {
   comando_recibido1 = getch();    // Lee el caracter ( tendria que recibir un "OK")

//Comprovar que reciba  "OK"
while (strcmp(comando_recibido1, comando_recibido_ideal)== 1 ){  // Son distintos
      error_comando=1;
 }
if(strcmp(comando_recibido1, comando_recibido_ideal) == 0 )  // Son iguales
      error_comando=0;
 }


La declaración de las variables es la siguiente:
Código: [Seleccionar]
const char * comando_recibido_ideal[]="OK";
const char * comando_recibido1[2];  // Es 2 porque espero recibir un OK

Espero que me ayuden, muchas gracias

Desconectado AngelGris

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2480
Re: Error al comparar dos strings con strcmp
« Respuesta #1 en: 12 de Enero de 2011, 13:57:48 »
  Hola Edu, como ví tu mensaje aquí (en la sección "Programadores") lo reporté al moderador para ver si lo podía cambiar a la sección "Primeros pasos" y dejarlo en el hilo que creaste "Problema: aparecen caracteres raros PIC18f4550 [Hi-tech PICC-18]" para que esté todo junto.

  Ahora paso a responder en base a tu consulta.

  En el caso de la definición de "comando_recibido_ideal" puede estar bien ya que sería una constante, de todos modos yo la definiría así

Código: C
  1. const char * comando_recibido_idea[2] = "OK";

  Pero en el caso de "comando_recibido", no es constante ya que en ella vas a escribir lo que recibas por el RS232. Para este caso se puede hacer lo siguiente

Código: C
  1. char BufferComando[2]; // declaro una variable de dos caracteres
  2. char * comando_recibido; // declaro un puntero a char
  3.  
  4. comando_recibido = BufferComando; // hago que el puntero apunte a la variable donde almacenaré el dato recibido

  De esa manera vas a poder comparar bien los dos string.

  De todas maneras a mi se me había ocurrido otra opción y es que recibas los dos caracteres y los almacenes en BufferComando[0] y BufferComando[1] respectivamente y entonces se podría hacer un if de la siguiente manera

Código: C
  1. if (BufferComando[0] == 'O') && (BufferComando[1] == 'K')
De vez en cuando la vida
nos besa en la boca
y a colores se despliega
como un atlas

Desconectado edu1989

  • PIC18
  • ****
  • Mensajes: 275
Re: Error al comparar dos strings con strcmp
« Respuesta #2 en: 12 de Enero de 2011, 14:54:23 »
Hola Angel,
Hoy he estado toqueteando y he llegado a esto:

Código: [Seleccionar]
//Primer comando AT
putst ("AT/n");

//Comprovar que reciba  "OK"
 while (getch_available() != false){ //Si hay un caracter disponible recibido por el puerto serie
 
if(getch_available()==true)
{
   //comando_recibido1 = UsartReadChar_nonstop();     
     cgets(comando_recibido1);
while (strcmp(comando_recibido1,"OK")== 1 ) // Son distintos
      error_comando=1;

if(strcmp(comando_recibido1,"OK") == 0 )  // Son iguales
      error_comando=0;
 
}
}

Con la declaración siguiente:
Código: [Seleccionar]
char  comando_recibido1[2];

Que te parece? Como puedes ver utilitzo una funcion nueva que sirve para leer una linea entrante en el terminal.

Muchas gracias.

Desconectado edu1989

  • PIC18
  • ****
  • Mensajes: 275
Re: Error al comparar dos strings con strcmp
« Respuesta #3 en: 12 de Enero de 2011, 15:33:07 »
Hola de nuevo Angel,
Para explicarte un poco lo que estoy haciendo he hecho una captura de pantalla para que todo se vea mas claro.

Hasta ahora yo mismo configuraba el modulo Bluetooth que conecto a mi PIC con esos comandos que puedes ver en la imagen. El modulo cuando los recibe, envia un OK.
Queda configurado correctamente despues del mensaje de "OK" de confirmacion de la instruccion atz. La linea de PAIR sale una vez desde el otro modulo pongo el PIN(1234) que se ha seleccionado mediante la instruccion at+btk="1234"

Posteriormente, desde el otro modulo Bluetooth he de buscar los dispositivos que hay conectados en el rango de cobertura y conectarme contra el mio. La linea Ring es cuando abro el terminal del otro modulo, automaticamente se produce una llamada y pasan a estar conectados.

Resumiendo: Tengo que ir enviando los comandos y esperando el OK. Despues hay que esperar a recibir el mensaje de ring y de connect para empezar el programa.

Espero que haya quedado 1 poco mas claro. Esa era mi intencion.  Voy a seguir mirando lo otro, cuando puedas dime algo.

Muchas gracias.

Desconectado AngelGris

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2480
Re: Error al comparar dos strings con strcmp
« Respuesta #4 en: 12 de Enero de 2011, 17:58:26 »

...........
Que te parece? Como puedes ver utilitzo una funcion nueva que sirve para leer una linea entrante en el terminal.

Muchas gracias.

  ¿La función que usas para leer toda una línea deja en la variable también el código correspondiente al CarrierReturn ( /n ), o sólo el string anterior a dicho código?

  Hay algo que no entiendo y es el porque dejás esta parte así...


Código: [Seleccionar]
.....
while (strcmp(comando_recibido1,"OK")== 1 ) // Son distintos
      error_comando=1;

if(strcmp(comando_recibido1,"OK") == 0 )  // Son iguales
      error_comando=0;
.....


  No sería conveniente hacer un if de esta manera...

Código: C
  1. if (strcmp (comando_recibido1, "OK") == 0) error_comando = 0;
  2. else
  3.   error_comando = 1;
De vez en cuando la vida
nos besa en la boca
y a colores se despliega
como un atlas

Desconectado edu1989

  • PIC18
  • ****
  • Mensajes: 275
Re: Error al comparar dos strings con strcmp
« Respuesta #5 en: 12 de Enero de 2011, 18:38:58 »
Gracias. Tienes razon.
Por lo que respecta a la funcion cgets, te parece que lo hago bien?
Código: [Seleccionar]
//Comprovar que reciba  "OK"
 while (getch_available() != false){ //Si hay un caracter disponible recibido por el puerto serie
 
if(getch_available()==true)
{
   //comando_recibido1 = UsartReadChar_nonstop();     
     cgets(comando_recibido1);

La funcion UsartReadChar_nonstop es la que implemente en el codigo pasado.
Antes me salian errores en la lectura, q te parece?

Gracias de antemano

Desconectado AngelGris

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2480
Re: Error al comparar dos strings con strcmp
« Respuesta #6 en: 12 de Enero de 2011, 18:53:59 »
Gracias. Tienes razon.
Por lo que respecta a la funcion cgets, te parece que lo hago bien?
Código: [Seleccionar]
//Comprovar que reciba  "OK"
 while (getch_available() != false){ //Si hay un caracter disponible recibido por el puerto serie
 
if(getch_available()==true)
{
   //comando_recibido1 = UsartReadChar_nonstop();     
     cgets(comando_recibido1);

La funcion UsartReadChar_nonstop es la que implemente en el codigo pasado.
Antes me salian errores en la lectura, q te parece?

Gracias de antemano

  Es que no tengo idea de como es la función cgets(). Así que no sabría decirte. Si podés, subí el código de la implementación de dicha función para ver como trabaja.
De vez en cuando la vida
nos besa en la boca
y a colores se despliega
como un atlas

Desconectado edu1989

  • PIC18
  • ****
  • Mensajes: 275
Re: Error al comparar dos strings con strcmp
« Respuesta #7 en: 12 de Enero de 2011, 18:56:15 »
Y con la funcion UsartReadChar_nonstop?
Ahora subire la implementacion de la funcion cgets.

Gracias de antemano

Desconectado AngelGris

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2480
Re: Error al comparar dos strings con strcmp
« Respuesta #8 en: 12 de Enero de 2011, 18:58:47 »
Y con la funcion UsartReadChar_nonstop?
Ahora subire la implementacion de la funcion cgets.

Gracias de antemano

  Subí la implementación de ambas así puedo comparar y además probarlas en mi PC para intentar ver como trabaja cada una.
De vez en cuando la vida
nos besa en la boca
y a colores se despliega
como un atlas

Desconectado edu1989

  • PIC18
  • ****
  • Mensajes: 275
Re: Error al comparar dos strings con strcmp
« Respuesta #9 en: 12 de Enero de 2011, 19:41:45 »
Ok, gracias. Subo las dos:

Ejemplo función cgets (del manual del hitech)
Código: [Seleccionar]
#include <conio.h>
#include <string.h>
char buffer[80];
void
main (void)
{
for(;;) {
cgets(buffer);
if(strcmp(buffer, "exit") == 0)
break;
cputs("Type ’exit’ to finish\n");
}
}

Su definicion viene como:
Código: [Seleccionar]
The cgets() function will read one line of input from the console into the buffer passed as an argument.
It does so by repeated calls to getche(). As characters are read, they are buffered, with
backspace deleting the previously typed character, and ctrl-U deleting the entire line typed so far.
Other characters are placed in the buffer, with a carriage return or line feed (newline) terminating
the function. The collected string is null terminated.


Subo la función UsartReadChar_nonstop
Código: [Seleccionar]
unsigned char UsartReadChar_nonstop(void)
{
  if (!RCIF) // TRMT1 is set when TSR is empty
    return 0;   
  return RCREG;
}

Desconectado AngelGris

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2480
Re: Error al comparar dos strings con strcmp
« Respuesta #10 en: 12 de Enero de 2011, 20:08:21 »
  Por lo que entiendo de la descripción, cgets() terminaría sólo si se recibe el CarrierReturn. Así que para que funcione en tu caso, el dispositivo tendría que responderte al comando con OK CarrierReturn, osea OK/n. Si es así te va a ir perfecto.

  Y me parece que UsartReadChar_nonstop(); lo que hace es ver como está el flag RCIF y si está en 1 (que indicaría que hay un caracter en el registro RCREG) lo lee y sino devuelve 0. Pero el nonstop parece referirse a que la función no se queda esperando que haya un caracter.
De vez en cuando la vida
nos besa en la boca
y a colores se despliega
como un atlas

Desconectado edu1989

  • PIC18
  • ****
  • Mensajes: 275
Re: Error al comparar dos strings con strcmp
« Respuesta #11 en: 12 de Enero de 2011, 20:18:58 »
Voy a mirar pero creo que si que responde con retorno de carro. Implementaremos la primera opcion entonces no?

Edito2: En el manual pone exactamente:
Código: [Seleccionar]
All commands are terminated by the carriage return character 0x0d, which is represented by the string <cr> in descriptions below this cannot be changed

Código: [Seleccionar]
All responses from the EZURiO device have carriage return and linefeed characters preceding and appending the response. These dual character sequences have the values 0x0D and 0x0A respectively and shall be represented by the string <cr,lf>.
« Última modificación: 12 de Enero de 2011, 20:44:18 por edu1989 »

Desconectado edu1989

  • PIC18
  • ****
  • Mensajes: 275
Re: Error al comparar dos strings con strcmp
« Respuesta #12 en: 13 de Enero de 2011, 08:28:03 »
Hola de nuevo

Me tira un error en la linia:
if (strcmp(&comando_recibido1,&comando_recibido_ideal)== 0 )

Tanto si lo pongo asi como si lo pongo:
if (strcmp(&comando_recibido1,"OK")== 0 )

En los dos casos: conflicting declarations for variable

Por otro lado, creo que la funcion cgets funcionara mejor que la otra despues de leer que el dispositivo devolvia las instrucciones con retorno de carro.

Voy a seguir trabajando
Gracias

Desconectado AngelGris

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2480
Re: Error al comparar dos strings con strcmp
« Respuesta #13 en: 13 de Enero de 2011, 09:57:03 »
Hola de nuevo

Me tira un error en la linia:
if (strcmp(&comando_recibido1,&comando_recibido_ideal)== 0 )

Tanto si lo pongo asi como si lo pongo:
if (strcmp(&comando_recibido1,"OK")== 0 )

En los dos casos: conflicting declarations for variable

Por otro lado, creo que la funcion cgets funcionara mejor que la otra despues de leer que el dispositivo devolvia las instrucciones con retorno de carro.

Voy a seguir trabajando
Gracias

  En la función strcmp no tenés que usar & antes de la variable. Te muestro un pequeño ejemplito que hice para probar simplemente la función de comparación y justamente funciona bien.

Código: C
  1. #include <htc.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4.  
  5. __CONFIG (HS & LVPDIS & WDTDIS);
  6.  
  7. #include "Def16f87xa.h"
  8. #pragma psect maintext=cuerpo
  9. void main(void)
  10. {
  11.   char Palabra2[2];
  12.   const char * ComandoIdeal = "OK";
  13.   char * ComandoRecibido;
  14.   char resultado = 10;
  15.   char PruebaConIf = 10;
  16.  
  17.   ComandoRecibido = Palabra2;
  18.   Palabra2[0] = 'O';
  19.   Palabra2[1] = 'K';
  20.   resultado = strcmp (ComandoIdeal, ComandoRecibido);
  21.  
  22.   resultado = strcmp (Palabra2, "OK");
  23.  
  24.   if ((Palabra2[0] == 'O') && (Palabra2[1] == 'K')) PruebaConIf = 0;
  25.   while (1);
  26. }

  Fijate que hice varias formas de controlar si lo recibido era OK (en este caso está almacenado en la variable Palabra2) y en todas funciona bien
De vez en cuando la vida
nos besa en la boca
y a colores se despliega
como un atlas

Desconectado edu1989

  • PIC18
  • ****
  • Mensajes: 275
Re: Error al comparar dos strings con strcmp
« Respuesta #14 en: 13 de Enero de 2011, 10:20:39 »
Si comento la linia que lee los datos del puerto serie no da ningun error. Al final que crees que es mejor usar, la funcion cgets o la usart?
Ahora mismo tengo el programa asi:

Código: [Seleccionar]
char Palabra2[2];
const char * ComandoIdeal = "OK";
char * ComandoRecibido;
char resultado = 10;

Código: [Seleccionar]

//Primer comando AT

putst ("AT/n");
LED0=1;
LED1=1;
//Comprovar que reciba  "OK"
 while (getch_available() != false){ //Si hay un caracter disponible recibido por el puerto serie
LED0=0;
LED1=0;
LED2=1;
LED3=1;
if(getch_available()==true)
{
ComandoRecibido = Palabra2;
//cgets(ComandoRecibido);
resultado = strcmp (ComandoIdeal, ComandoRecibido);


if(resultado==0){ // Iguales
error_comando=0;
LED2=0;
LED3=0;
}
else
    error_comando=1;
  LED2=0;
LED3=0;
}
}

Voy haciendo que se enciendan los leds para que cuando grabe en la placa pueda ver facilmente donde esta el error.
Voy a mirar la funcion para leer, hechale un hojo si puedes y despues comentamos la jugada

Gracias de antemano amigo.
« Última modificación: 13 de Enero de 2011, 12:18:42 por edu1989 »