Comparación de cadenas

Iniciado por kaostias, 24 Octubre 2013, 09:43 AM

0 Miembros y 2 Visitantes están viendo este tema.

kaostias

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.
- ¡Éste código sin documentar es un galimatías!
- Es tuyo, de hace 3 semanas
- ¡Es una obra maestra aunque esté sin documentar! ¿Qué decías que hace?

eferion

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.

kaostias

#2
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
- ¡Éste código sin documentar es un galimatías!
- Es tuyo, de hace 3 semanas
- ¡Es una obra maestra aunque esté sin documentar! ¿Qué decías que hace?

amchacon

En C:

strcmp(Cadena 1, Cadena 2);

Devuelve 0 si las cadenas son iguales.
Por favor, no me manden MP con dudas. Usen el foro, gracias.

¡Visita mi programa estrella!

Rar File Missing: Esteganografía en un Rar

kaostias

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.
- ¡Éste código sin documentar es un galimatías!
- Es tuyo, de hace 3 semanas
- ¡Es una obra maestra aunque esté sin documentar! ¿Qué decías que hace?

eferion

Cita de: 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

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.

Cita de: amchacon en 24 Octubre 2013, 13:23 PM
En C:

strcmp(Cadena 1, Cadena 2);

Devuelve 0 si las cadenas son iguales.

Se te olvidaron las comillas

strcmp("Cadena 1", "Cadena 2");

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

ivancea96

Cita de: eferion en 24 Octubre 2013, 13:37 PM
Se te olvidaron las comillas
En realidad creo que amchacon puso Cadena 1 refiriendose a una variable, no a una cadena como constante.

kaostias

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.


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;
}
- ¡Éste código sin documentar es un galimatías!
- Es tuyo, de hace 3 semanas
- ¡Es una obra maestra aunque esté sin documentar! ¿Qué decías que hace?

eferion

#8
Cita de: ivancea96 en 24 Octubre 2013, 14:19 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?

Cita de: 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.

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.

Cita de: kaostias en 24 Octubre 2013, 14:32 PM

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.

rir3760

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:
char linea[ALGUN_VALOR];
int numero;

/* ... */

if (sscanf(linea, "add %d", &numero) == 1){
   /* comando add */
}else if (sscanf(linea, "mul %d", &numero) == 1){
   /* comando mul */
}


Un saludo
C retains the basic philosophy that programmers know what they are doing; it only requires that they state their intentions explicitly.
--
Kernighan & Ritchie, The C programming language