[C con Clase] Tratamiento de cadenas

Alejandro alepelexo en yahoo.es
Mie Ene 30 18:13:58 CET 2008


¡Hola lista! Cada vez me asusto más mirando lo que perdí en los escasos meses que dejé de programar... ¡ya no doy hecho ni la función que quiero. Tras decidir usar la idea de Steven de la librería cstring, me surjen ciertos problemas entre cadenas y punteros que me tiene algo descolocado. La función es ésta:

char* ModTexto(char inicial[128], int jug, int oponente)

Y en su interior, por partes, tengo ésto para resolverlo de la forma qe me aconsejó Steven:

1.  Buscar '%' en la cadena: original

      char definitiva[128];//Cadena definitiva
      int k, i, x;//Contadores
      char busca = '%';//Caracter a buscar
      
      for(k = 0; inicial[k] != busca; k++);



2.  Copiar la subcadena de original hasta '%' al final de: resultado (aquí se presenta el primer problema)

      strncat(definitiva, inicial, k);

Como ya me da un problema, no sigo. A contnuación escribo "return definitiva" y lo que me devuelve es la cadea "a9D" o similar. No estoy seguro de cuál es el problema, pero intuyo que es algo relacionado con los punteros/cadenas/funciones que devuelven cadenas. Y como ya dije, hace varios meses que no programo y tengo algo olvidados esos temas... ¿Alguna ayuda?

Gracias y un saludo, Alejandro.

El pasado 2008-01-30 14:28:10, Alejandro escribió:
 
A> ¡Muchas gracias! Creo que trataré de usar la librería <cstring> y sus respectivas funciones, es la opción más simple, se adapta a todos los casos y es la que mejor comprendo (lo cual es muy importante). De nuevo gracias por tu ayuda.
A> Un saludo, Alejandro.
A> El pasado 2008-01-29 16:00:40, Steven escribió:
A>  
A> S> Hola Alejandro,
A> S> 
A> S> Alejandro wrote:
A> S> 
A> S> > ¡Hola lista! Tengo un pequeño problema con una función que realiza
A> S> > cierto tratamiento sobre una cadena. Éste es el código de la función:
A> S> >
A> S> 
A> S> [CORTE]
A> S> 
A> S> >
A> S> > Pues bien, lo que yo quiero es que me transforme una cadena del tipo
A> S> > "Vaya! %j le ha dado un buen golpe a %o!". Decha cadena estaría en un
A> S> > arcjivo de texto y lo que quiero es que sustituya los caracteres "%j"
A> S> > y "%o" por los nicks de un jugador y su oponente. Dichos nicks se
A> S> > introducen al principo del programa. Ahora voy a contar mi problema.
A> S> > Si la cadena es como dije y acaba con un caracter normal, no tengo
A> S> > ningún problema. Pero cuando la cadena que intento tratar acaba por
A> S> > "%o" o por "%j" se me añaden unas sopechosas símbolos al final de la
A> S> > cadena, tras un salto de línea. Supongamos que el nick del jugador es
A> S> > "Jug1" y el del oponente es "Opon". Pues si yo intento tratar la
A> S> > cadena "Vaya! Un gran ataque de %j golpea a %o!" el resultado es:
A> S> > "Vaya! Un gran ataque de Jug1 golpea a Opon!". Perfecto. Sin embargo,
A> S> > si yo intento tratar la cadena "Vaya! Un gran ataque de %j golpea a
A> S> > %o" el resultado es: "Vaya! Un gran ataque de Jug1 golpea a Opon
A> S> > w2s". Además de w2s me aparecen otros símbolos raros, hasta completar
A> S> > un total de cuatro. Dichos símbolos aparecen tras un salto de
A> S> > línea... ¿A qué se debe?
A> S> >
A> S> 
A> S> Tienes un error al usar 'auxiliar' cuando quieres asignar el valor de 0
A> S> inicialmente. Escribes:
A> S> 
A> S> for( int y = 0; auxiliar[y]; y++ )
A> S> {
A> S>   auxiliar[y] = 0;
A> S> }
A> S> 
A> S> Como 'auxiliar' no fue inicializado, éste contiene basura. Además, lo
A> S> que realmente quieres es usar el valor de 512, porque es el valor
A> S> máximo. Esto sería,
A> S> 
A> S> for( int y = 0; y < 512; y++ )
A> S> {
A> S>   auxiliar[y] = 0;
A> S> }
A> S> 
A> S> El otro problema es que no asignas el carácter nulo al final de la
A> S> cadena en 'definitiva'. Ten presente que estás construyendo una cadena
A> S> de caracteres desde cero y por tanto necesitas agregar un cero al final.
A> S> 
A> S> 
A> S> De todos modos, sugiero usar las funciones estándares de <cstring> para
A> S> realizar estas manipulaciones. Específicamente, las funciones 'strchr()'
A> S> y 'strncat()'. La primera sirve para buscar un carácter en una cadena y
A> S> la segunda para copiar x caracteres de una cadena al final de otra. El
A> S> esquema del algoritmo sería algo así:
A> S> 
A> S> 1.  Buscar '%' en la cadena: original
A> S> 2.  Copiar la subcadena de original hasta '%' al final de: resultado
A> S> 3.  Si el siguiente carácter es 'j', entonces
A> S> 4.     Copiar jugador.nombre al final de resultado
A> S> 5.  Si no y el siguiente carácter es 'o', entonces
A> S> 6.     Copiar oponente.nombre al final de resultado
A> S> 7.  Repetir los pasos #1-#6 hasta que lleguemos al final de original
A> S> 8.  Terminar( resultado )
A> S> 
A> S> Básicamente vamos encontrando y copiando subcadenas en la cadena
A> S> original. Estamos haciendo algo parecido a esto:
A> S> 
A> S> char szResultado[512];
A> S> 
A> S> strcpy( szResultado, "Vaya! " );
A> S> strcat( szResultado, jugador.nombre );
A> S> strcat( szResultado, " le ha dado un buen golpe a " );
A> S> strcat( szResultado, oponente.nombre );
A> S> strcat( szResultado, "!" );
A> S> 
A> S> 
A> S> Otra solución podría ser la siguiente. Encontrar cada pareja "%j" y "%o"
A> S> y sustituirlos por "%s". Posteriormente, invocamos 'sprintf()' pasando
A> S> las cadenas necesarias. El comportamiento sería el siguiente:
A> S> 
A> S> formato <- "Vaya! %j le ha dado


Más información sobre la lista de distribución Cconclase