Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: kaostias en 24 Octubre 2013, 09:43 am



Título: Comparación de cadenas
Publicado por: kaostias en 24 Octubre 2013, 09:43 am
Buenas, este es mi primero mensaje y espero que no el último. Llevo tiempo programando en java y me pasé hace muy poco  a c++ y c, por que mi carrera me lo exigía, así que ahora estoy haciendo mi primer módulo para el kernel de un debian 6, Es una práctica para la universidad y se trata de una lista que guarde y borre elementos de proc y en la que, si se modifica un archivo de  /proc  tiene que reconocerlo y ejecutar el código correspondiente, digamos que se debe añadir un número a la lista, pues el usuario escribirá: echo add 10 > /proc/mymodule. Aún soy muy inexperto con C y tengo un error que seguro es de principiante.

¿Cómo puedo estar seguro de que el formato de una cadena es del tipo: "add 144" o "remove 4"?

Gracias.


Título: Re: Comparación de cadenas
Publicado por: eferion en 24 Octubre 2013, 10:00 am
Si el formato de una instrucción es "comando[espacio/s]argumento", existe una función muy chula llamada strchr que permite dividir una cadena de caracteres a partir de un caracter que hace las veces de delimitador... en tu caso el delimitador sería el espacio.

Después de trocear la cadena recorres las subcadenas y lo suyo es que sólo encontrases dos subcadenas... la primera sería el comando y la segunda el argumento.

El algoritmo también te permitirá trabajar con más de un argumento.

La opción 2 consiste en recorrerte a mano la cadena e ir buscando los espacios para delimitar el comando y los argumentos.


Título: Re: Comparación de cadenas
Publicado por: kaostias en 24 Octubre 2013, 10:11 am
Un profesor me comentó que existía una macro del tipo

char* str = "add 134";

int aux;
strcmp(str, "add %d",aux)

Que devuelve un número igual a 1 si las cadenas son iguales, y guarda en aux el dígito %d, pero por mucho que busco no logro encontrarlo


Título: Re: Comparación de cadenas
Publicado por: amchacon en 24 Octubre 2013, 13:23 pm
En C:

Código
  1. strcmp(Cadena 1, Cadena 2);

Devuelve 0 si las cadenas son iguales.


Título: Re: Comparación de cadenas
Publicado por: kaostias en 24 Octubre 2013, 13:36 pm
Es cierto, lo que yo quería era encontrar algo de ese tipo (He puesto strcmp por poner algo) que pueda comparar que el formato de la cadena se ajuste a eso "add+número" y me devuelva el número.


Título: Re: Comparación de cadenas
Publicado por: eferion en 24 Octubre 2013, 13:37 pm
Un profesor me comentó que existía una macro del tipo

char* str = "add 134";

int aux;
strcmp(str, "add %d",aux)

Que devuelve un número igual a 1 si las cadenas son iguales, y guarda en aux el dígito %d, pero por mucho que busco no logro encontrarlo

No es una macro, es una función y su uso es tal y como te ha comentado amchacon. Las macros son bastante diferentes a las funciones.

Por otro lado no es tan complicado de buscar... tu pon strcmp en google y curiosamente el primer enlace que sale te explica el funcionamiento de dicha función.

Por otro lado, strcmp no es capaz de reconocer parámetros ( lo digo por el %d que has plantado ahí )... compara cadenas caracter a caracter. Si quieres que la comparación busque por conceptos más abstractos ( es decir, primero un texto que representa a un comando y después un número ) tendrás que optar por comprobar tu a mano la secuencia... para ello puedes hacer uso de mi primer mensaje.

En C:

Código
  1. strcmp(Cadena 1, Cadena 2);

Devuelve 0 si las cadenas son iguales.

Se te olvidaron las comillas

Código
  1. strcmp("Cadena 1", "Cadena 2");

Se que lo sabías, el comentario era sobretodo para no liar a terceros.


Título: Re: Comparación de cadenas
Publicado por: ivancea96 en 24 Octubre 2013, 14:19 pm
Se te olvidaron las comillas
En realidad creo que amchacon puso Cadena 1 refiriendose a una variable, no a una cadena como constante.


Título: Re: Comparación de cadenas
Publicado por: kaostias en 24 Octubre 2013, 14:32 pm
Gracias a todos. De momento me lo intento apañar con este script, sólo tengo el problema de que atoi no está en kernel, y no sé cómo parsear un entero a dígito en kernel.

Código:
int reconocedor(char* str, int* dig){
if(strncmp(str, "add ", 4)==1){
*dig = atoi(str[4]);
return 1;
}else if(strncmp(str,"remove ", 7)==1){
*dig = atoi(str[7]);
return 2;
}else if(strcmp(str,"cat") == 1) {
*dig = -1;
return 3;
}
if(strcmp(str, "sort") == 1) {
*dig = -1;
return 4;
}
*dig = -1;
  return -1;
}


Título: Re: Comparación de cadenas
Publicado por: eferion en 24 Octubre 2013, 14:45 pm
En realidad creo que amchacon puso Cadena 1 refiriendose a una variable, no a una cadena como constante.

Entonces "técnicamente" tendría que haber eliminado los espacios, no?

Gracias a todos. De momento me lo intento apañar con este script, sólo tengo el problema de que atoi no está en kernel, y no sé cómo parsear un entero a dígito en kernel.

Tan "complicado" como recorrer la cadena, reconocer el dígito actual, multiplicar por diez el total acumulado y sumarle el valor del dígito actual al acumulado.

Código:
int reconocedor(char* str, int* dig){
if(strncmp(str, "add ", 4)==1){
*dig = atoi(str[4]);
return 1;
}else if(strncmp(str,"remove ", 7)==1){
*dig = atoi(str[7]);
return 2;
}else if(strcmp(str,"cat") == 1) {
*dig = -1;
return 3;
}
if(strcmp(str, "sort") == 1) {
*dig = -1;
return 4;
}
*dig = -1;
  return -1;
}

Creo que no tienes demasiado claro lo que estás haciendo... strcmp compara dos cadenas... si ambas son iguales, devuelve cero, en caso contrario devuelve un número distinto de cero... si chequeas strcmp con 1 ya te digo yo que el código no te va a funcionar.


Título: Re: Comparación de cadenas
Publicado por: rir3760 en 24 Octubre 2013, 15:18 pm
En este caso una alternativa a strcmp es sscanf (prototipo en <stdio.h>) para verificar si coincide la primera palabra y al mismo tiempo extraer el numero entero. Esa función opera de forma similar a scanf pero en lugar de obtener los caracteres de la entrada estándar utiliza la cadena indicada como su primer argumento.

Por ejemplo:
Código
  1. char linea[ALGUN_VALOR];
  2. int numero;
  3.  
  4. /* ... */
  5.  
  6. if (sscanf(linea, "add %d", &numero) == 1){
  7.   /* comando add */
  8. }else if (sscanf(linea, "mul %d", &numero) == 1){
  9.   /* comando mul */
  10. }

Un saludo


Título: Re: Comparación de cadenas
Publicado por: kaostias en 24 Octubre 2013, 16:05 pm
Muchísimas gracias, era justo lo que andaba buscando. Ahora sólo me queda aclararme las ideas con las declaraciones estáticas que no me dejan compilar y punto.

En este caso una alternativa a strcmp es sscanf (prototipo en <stdio.h>) para verificar si coincide la primera palabra y al mismo tiempo extraer el numero entero. Esa función opera de forma similar a scanf pero en lugar de obtener los caracteres de la entrada estándar utiliza la cadena indicada como su primer argumento.

Por ejemplo:
Código
  1. char linea[ALGUN_VALOR];
  2. int numero;
  3.  
  4. /* ... */
  5.  
  6. if (sscanf(linea, "add %d", &numero) == 1){
  7.   /* comando add */
  8. }else if (sscanf(linea, "mul %d", &numero) == 1){
  9.   /* comando mul */
  10. }

Un saludo