[C] ayuda, programa compila bien pero no cumple la funcion (solucionado)

Iniciado por xiruko, 15 Abril 2012, 21:21 PM

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

xiruko

buenas gente, estoy tratando de hacer un programa que le pases una palabra y una frase, y te diga cuantas veces esta la palabra en la frase. estoy tratando de hacerlo con punteros y funciones para ir practicando, asi que seguro que no es la manera mas eficiente de hacerlo. pero bueno, el codigo es el siguiente:

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

#define WORD 10
#define SENTENCE 50

int longitud_cadena (char* a);
void comparar_cadenas (char* s, int i, char* w, int lw, int* words);

int main() {
 
 char *w,*s;
 int i,long_w,long_s,words;
 
 w=(char*) calloc(WORD,sizeof(char));
 s=(char*) calloc(SENTENCE,sizeof(char));
 
 words=0;
 
 printf("Introduce una palabra de maximo %d caracteres:\n",WORD-2);
 fgets(w,WORD,stdin);
 long_w=longitud_cadena(w);
 
 printf("Introduce una frase de maximo %d caracteres:\n",SENTENCE-2);
 fgets(s,SENTENCE,stdin);
 long_s=longitud_cadena(s);
 
 for(i=0;i<long_s;i++) {
   if(*(s+i)==*w) { comparar_cadenas(s,i,w,long_w,&words); }
 }
 
 printf("La palabra ocurrio %d veces.\n",words);
 return 0;
}

int longitud_cadena (char* a) {
 
 int num_ch,i;
 num_ch=0;
 for(i=0;(int)*(a+i)!=10;i++) { num_ch++; }
 return(num_ch);
}

void comparar_cadenas (char* s, int i, char* w, int lw, int* words) {
 
 int n;
 
 for(n=0;n<lw;n++) {
   if(*(s+i+n)!=*(w+n)) { break; }
 }
 if(n==lw) { (*words)++; }
}


el tema es que compila bien, pero siempre me dice que la palabra ocurrio 0 veces en la oracion. llevo 2 horas repasandolo y siguiendo el flujo del programa con papel y boli y es que no doy con el fallo.

alguien me echa un cable? la verdad se agradeceria... no quiero irme a dormir sin verlo funcionando xD

gracias!

EDITADO: añadido algunas correcciones y ahora casi funciona, la salida marca 1 si la palabra aparece una o mas veces, y marca 0 si la palabra no se encuentra en la frase.

EDITADO2: ya funciona correctamente. por si a alguien le interesa, el error estaba en la funcion longitud_cadena que devolvia 1 caracter mas de la cuenta.

gracias por la ayuda!

durasno

Hola! el error esta en usar scanf para ingresar una frase. Si vos qres ingresar algo como "Hola soy una frase", scanf lee hasta encontrar un blanco, osea solo se va a guardar en s: "Hola". Para ingresar frases podes usar: gets, fgets o crear tu propia funcion para entrada de cadenas
Otro error es: if(n+1==lw). Si las palabras son iguales, n ya va a ser igual a lw, no es necesario sumarle 1

Saludos
Ahorrate una pregunta, lee el man

xiruko

muchas gracias por contestar, justo ahora estaba buscando en google acerca de la funcion scanf y los espacios...

respecto a lo de if(n+1==lw), n corresponde al indice de la cadena y empiezo por n=0, y lw son los caracteres que tiene la palabra a buscar. asi que si una palabra tiene 4 caracteres, significa que su indice va de 0 a 3, por eso ahi hago n+1, ya que si en el for no se ha encontrado ninguna diferencia de caracteres, n valdra 3 y lw 4.

durasno

mmm estas seguro? Te funciona bien sumandole 1??

Saludos
Ahorrate una pregunta, lee el man

xiruko

pues no se si funciona bien ya que aun no he conseguido que funcione... xD

he probado con la funcion gets(), he buscado en google y dice que esta en la libreria stdio.h, pero cuando ejecuto el programa es como si no hubiera ninguna funcion gets() y no me deja introducir la frase.

sabes por que pasa esto?

diria que es n+1 ya que me he hecho un par de ejemplos con papel y boli y se cumplia para n+1, aunque quizas tengas razon y sea solo n. a ver cuando pueda hacerlo funcionar...

durasno

El problema es al usar scanf primero, despues de ingresar una palabra se tipea el ENTER el cual queda almacenado en el bufer de entrada y gets toma ese ENTER sin dejarte ingresar la frase
Para que no tome el enter podes hacer
scanf("%s",w);getchar();

o usar dos gets
gets(s)
gets(w)
Ahorrate una pregunta, lee el man

xiruko

#6
muchas gracias de nuevo! he mirado lo del n+1 y tenias razon, no hay que sumarle nada ya que n valdra lw si ha hecho todo el ciclo correctamente.

he probado poniendo dos fgets() (para limitarle a que guarde solo un nº de caracteres entrados por stdin) y ahora al menos reacciona y marca que ocurrio 1 vez, aunque sean 10 xD

edito el primer post para incluir las modificaciones, y mañana sigo revisando porque no funciona ya que me tengo q ir en nada.

gracias por todo!

EDITO: he conseguido que funcione, el error estaba en la funcion longitud_cadena la cual devolvia 1 caracter mas de la cuenta.

me habia parecido leer que la funcion gets() eliminaba el caracter de salto de linea, pero he hecho una prueba rapida pasando a (int) los caracteres y en la cadena los dos ultimos digitos eran "10 0", que seria un salto de linea y un nulo respectivamente. asi que en la funcion longitud_cadena tan solo habia que cambiar el if, que en vez de compararlo con "0" se tenia que hacer con "10".