Error programa encontrar una cadena dentro de otra

Iniciado por David8, 9 Abril 2014, 00:16 AM

0 Miembros y 1 Visitante están viendo este tema.

David8

Tengo que hacer un programa que verifique si una cadena se encuentra dentro de otra ( sin usar la función strstr() ). Este es el código:


#include<stdio.h>
#include<stdlib.h>
#include<string.h>

short int fBuscar(char *ptrX, char *ptrY, short int longitud);   // prototipo función fBuscar

short int fBuscar(char *ptrX, char *ptrY, short int longitud)
{
short int contador1 = 0;
short int contador2 = 0;
char *ptrZ = ptrY;   // usamos ptrZ como una variable auxiliar que almacena la dirección en memoria de cadenaABuscar[0]

for(; *ptrX != '\0'; ptrX++){

if(*ptrX == *ptrY){
contador1++;
contador2++;
ptrY++;   // ptrY apunta a la siguiente posición de memoria

if(contador1 == longitud){
return (contador2 - longitud);
}
}
else{
ptrY = ptrZ;
contador1 = 0;
contador2++;
}
}

return (-1);   // si se llega hasta aquí no se ha encontrado la cadenaABuscar en cademaOriginal
}

int main(void)
{
const short int tamanio;
int c;
printf("Definir tama%co aproximado de la cadena: ", 164);
scanf("%d", &tamanio);

while((c = getchar()) != '\n');   // limpieza del buffer

char cadenaOriginal[tamanio];   // cadena donde vamos a buscar
char cadenaABuscar[tamanio];   // cadena de caracteres que queremos ver si se encuentra en cadenaOriginal
short int longitud;
short int x;   // el valor de x verifica si la cadenaABuscar se encuentra en cadenaOriginal

puts("\nIntroducir cadena donde se quiere buscar:");
fgets(cadenaOriginal, tamanio, stdin);

puts("\nIntroducir cadena que queremos buscar:");
fgets(cadenaABuscar, tamanio, stdin);

longitud = strlen(cadenaABuscar) - 1;   // evitamos contar el caracter '\n' que almacena fgets()

x = fBuscar(cadenaOriginal, cadenaABuscar, longitud);

if(x == -1){
puts("Cadena no contenida");
}
else{
puts("Cadena no contenida");
printf("Encontrada en la posicion %d", x+1);
}

return EXIT_SUCCESS;
}



El problema es que al introducir por ejemplo hhola y después hola me da error porque de las h los punteros ptrX y ptrY saltan a la h y la o respectivamente.
No sé como arreglarlo. (SEGURAMENTE HAYA MÁS FALLOS)

Gracias

rir3760

Cita de: David8 en  9 Abril 2014, 00:16 AMTengo que hacer un programa que verifique si una cadena se encuentra dentro de otra ( sin usar la función strstr() ).
La aproximación que tomas esta mal ya que si sucede una coincidencia parcial, por ejemplo si buscas "aab" en "aaab", los caracteres no se vuelven a verificar (en el ejemplo la búsqueda debe continuar a partir del segundo carácter).

Si la cadena es "s" y la subcadena a buscar es "t" la forma mas sencilla (fuerza bruta) es verificando cada posición de "s", por cada una revisas si los caracteres coinciden con la subcadena "t".

Un ejemplo de ello sencillo y sin funciones:
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
   char *s = "anita lava la tina";
   char *t = "tina";
   
   int i;
   int j;
   
   for (i = 0; s[i] != '\0'; i++){
      for (j = 0; s[i + j] == t[j] && t[j] != '\0'; j++)
         ;
     
      if (t[j] == '\0')
         printf("Coincidencia en la posicion %d\n", i);
   }
   
   return EXIT_SUCCESS;
}


Cita de: David8 en  9 Abril 2014, 00:16 AMSEGURAMENTE HAYA MÁS FALLOS
Me temo que si. Algunos de ellos:

* La variable "tamanio" la declaras como solo lectura (calificador const) y después la utilizas para almacenar ahí un valor con scanf. Elimina ese calificador.

* Cuando se utiliza un bucle para descartar el resto de la linea debes verificar el caso de error o fin de archivo, ese bucle hay que cambiarlo a:
while ((c = getchar()) != EOF && c != '\n')
   ;


* Cuando declaras un array e indicas el numero de elementos mediante un valor calculado en tiempo de ejecución (tu caso con los arrays "cadenaOriginal" y "cadenaABuscar") si es valido depende del compilador.

* No utilices "truquitos" como este:
printf("Definir tama%co aproximado de la cadena: ", 164);
Para imprimir caracteres fuera del juego de caracteres ASCII porque los entornos de edición y ejecución dependen de la implementación. En buen cristiano caracteres como la 'ñ' no están garantizados (evitalos salvo una buena razón).

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

David8

Hice unos pequeños cambios en la función fBuscar y me funciona.
Pero no entiendo porque no puedo declarar a "tamanio" como const. El compilador no me da ningún warning y si me deja escribir en el ( la primera vez, lo he comprobado imprimiendo el  valor).

Gracias por los consejos, lo del fin de archivo creía que solo se ponía cuando se trabaja con ellos.

Un saludo  :D

noele1995

Bueno si la declaras como const es para que sea constante, si la vas a querer modificar entonces quitale el const ya que este sirve para indicar que no se va a modificar.

Saludos

David8

Eso quería decir. Es que según me lo puso rir3760 entendí que al momento de declararlo como const ya quedaba invariable aún sin tener ningún valor almacenado. Pero me resultaba raro ya que "obviamente" funciona.

Un saludo

noele1995

Bueno aunque te deje modificarlo no deberias, y creo puede desencadenar errores inesperados y/o diferentes resultados dependiendo del compilador y ordenador.

Saludos

David8


rir3760

Cita de: David8 en  9 Abril 2014, 12:11 PMPero no entiendo porque no puedo declarar a "tamanio" como const. El compilador no me da ningún warning
Para que se generen los mensajes debes utilizar el modo mas estricto que tu compilador permita y ello debe indicarse claramente en su documentación.

Por ejemplo si este programa:
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
   const int a = 42;
   
   a = 69;
   printf("%d\n", a);
   
   return EXIT_SUCCESS;
}

Lo compilamos en la forma indicada utilizando Lcc-win32, Pelles C, CygMing (la version de gcc para Cygwin) y Visual C++ 2008 Express la salida es:
Lc.exe -A -ansic -check main.c

main.c:8:Error:assignment to const identifier 'a'
----
Pocc /Zs /W2 main.c

main.c(8): error #2032: Assignment to const identifier 'a'.
----
gcc (GCC) 4.7.3
gcc.exe -c -ansi -pedantic -Wall -O main.c -o main.tmp

main.c: In function 'main':
main.c:8:4: error: assignment of read-only variable 'a'
----
CL.exe /TC /Zs /Za /Wall /W4 /D_CRT_SECURE_NO_WARNINGS main.c

main.c(8) : error C2166: Valor L especifica un objeto const


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

David8

Efectivamente como dices si intento modificar la variable declarada con const con un valor previamente ya almacena me da error (lo que no sé es si tengo el compilador en modo estricto, supongo que no). Lo que pasa es que me parece que entendí mal lo que me dijiste. Interpreté que si ponías por ejemplo:

const cadena[tamanio];

Y luego le asignabas un valor debía de dar un error, (si la asignación ocurre solo una vez sin tener cadena ningún valor previo).
Por eso digo que es culpa mía de no haberlo interpretado bien.

Un saludo