Hack x Crack - Comunidad de Seguridad informática

Programación => C / C++ => Mensaje iniciado por: r1ghtz0 en Abril 07, 2013, 03:22:34 am

Título: Ayuda con C contar apariciones de una letra en una cadena
Publicado por: r1ghtz0 en Abril 07, 2013, 03:22:34 am
Ejercicio:
Escribir un programa que cuente el numero de veces que aparece una letra en una secuencia de
caracteres acabada en ’.’

Código: [Seleccionar]

#include <stdio.h>
#include <math.h>

int main(void)
{char cad, let;
let= 'e';
unsigned rep, i;

printf("Introduzca una cadena de caracteres: ");
scanf("%c", &cad);

for(i= 0 ; i<=(int) cad; i++){
if(cad == let){
rep= 1;
}
else if(rep == 1){
rep= rep + 1;
}
if(rep != 1){
    rep= rep +1;
    }
        printf("\n La 'E' se repite %d veces \n", rep);
}

return 0;
}


Lo que pasa es que no encuentro la manera de almacenar más de un caracter en una variable, la letra que estoy siguiendo es la "E" y con la variable "rep" quiero mostrar las veces que se repite la "E". La forma que se me ocurrio es la de poner un "for" para que se repitiera conforme se ingresen letras, y allí en la condición del "for" estoy indicando que los caracteres introducidos en "cad" se transforman cada uno en su entero ASCII. Explico lo que quiero hacer con lo que está dentro del for, en el primer if quiero que evalue si el primer caracter es "E", si se cumple entonces rep= 1;
Código: [Seleccionar]
if(cad == let){
rep= 1;
}

Si de lo contrario rep ya tiene el valor de 1 entonces rep= rep+1;

Código: [Seleccionar]
else if(rep == 1){
rep= rep + 1;
}

Pero como rep no vale 1 en la primera ejecución del bucle entonces pasa al siguiente if:

Código: [Seleccionar]
if(rep != 1){
    rep= rep +1;
                  }

rep no es distinto que 1 en la primera ejecución del bucle por lo tanto esta condición tampoco se cumple. En la segunda ejecución del bucle rep si valdrá 1, por lo tanto quiero la primera condición no se cumpla si no que se cumplan las dos de abajo para se bayan sumando conforme condiga letras "E" en la cadena de caracteres.

Espero que me puedan aconsejar para hacer este ejercicio, de antemano gracias y les pido que no me digan que use matrices o arreglos, este ejercicio debe hacerce sin matrices.

Saludos
Título: Re:Ayuda con un ejercicio en en C
Publicado por: Jum4r0 en Abril 07, 2013, 08:30:25 am
Suponiendo que he entendido bien lo que quieres:
¿Por qué no esperas a que se ingresen letras? Lo cuentas al final.
Utiliza subíndices para comparar con el punto y la "e". Si es un punto, termina, si es una "e", incrementa el contador.
Título: Re:Ayuda con un ejercicio en en C
Publicado por: elpre en Abril 07, 2013, 01:21:31 pm
No sería más fácil con un array??? while(strcmp(cad,let) cont++;
Título: Re:Ayuda con un ejercicio en en C
Publicado por: r1ghtz0 en Abril 07, 2013, 10:13:45 pm
Suponiendo que he entendido bien lo que quieres:
¿Por qué no esperas a que se ingresen letras? Lo cuentas al final.
Utiliza subíndices para comparar con el punto y la "e". Si es un punto, termina, si es una "e", incrementa el contador.

Gracias por sus respuestas, me sigue dando el mismo resultado con arreglos y como ya dije anteriormente, no encuentro la forma en que el bucle evalúe cada una de las letras y hacer que se sumen solo las letras "e" que se ingresaron. Siempre me da el mismo resultado que es 1.

Código: [Seleccionar]
#include <stdio.h>
#include <math.h>

int main(void)
{
       char let, cad[20];
let= 'e';
unsigned rep, i;

printf("Ingrese una cadena de caracteres: ");
scanf("%c", &cad[20]);

for(i= 0 ; i<= cad[20] ; i++){
if(cad[20] == let){
rep= 1;
}

else if(rep != 1 && cad[20] == let){
    rep= rep +1;
    }
   
    else if(cad[20] == (char) 46){
rep= rep;
}
}
printf("\n La 'E' se repite %d veces \n", rep);

return 0;
}   

Otra cosa es con el segundo "if", yo no quiero que el segundo "if" se ejecute en la primera corrida del bucle si no en la segunda corrida, y en la segunda corrida el primer if no debe ejecutarse de modo que solo se ejecute el segundo "if" y en la tercera ejecución solo ejecutará el tercer "if", de modo que "rep" será distinto que 1 y cad[20] igual "let", entonces "rep" será igual al resultado dado por la suma de las dos primeras ejecuciones del bucle, desde la tecera ejecucuón del bucle en adelante solo se cumplirá el tercer y cuarto "if"
Título: Re:Ayuda con un ejercicio en en C
Publicado por: elpre en Abril 07, 2013, 11:30:21 pm
Pero si en la cadena están sienpre mirando el último caracter. Estás poneindo car[20] en vez de car
Título: Re:Ayuda con un ejercicio en en C
Publicado por: r1ghtz0 en Abril 07, 2013, 11:36:36 pm
Pero si en la cadena están sienpre mirando el último caracter. Estás poneindo car[20] en vez de car

ok pero no me estás diciendo especificamente en que parte del código, estoy usando es cad[20] no car[20] :p y entonces para que no miren siempre al ultimo caracter tendría que poner cad[1] cierto?
Título: Re:Ayuda con un ejercicio en en C
Publicado por: JAG en Abril 07, 2013, 11:57:39 pm
A ver... os estáis complicando mucho cuando en realidad esto es más sencillo de hacer... échale un ojo al código y si tienes alguna duda me dices vale?? Un saludo!!

Código: [Seleccionar]
#include <stdio.h>
#include <string.h>

int main(){
int longitud;
char cad[20];
char let = 'e';
int i, j=0;

printf("Ingrese su cadena: ");
scanf("%s", cad);
longitud = strlen(cad);

for(i=0;i<longitud;i++){
if(cad[i]==let){
j++;
}
}
printf("La letra %c aparece %i veces\n",let,j);
return 0;
}
Título: Re:Ayuda con un ejercicio en en C
Publicado por: elpre en Abril 08, 2013, 12:20:25 am
a eso me refería, cad. Tampoco quería poner el código entero, que lo tengo hecho de la misma forma, pero cada uno lo hace como lo ha pensado y creo que si has pensado de una forma lo mejor es seguir así.
Pero si en la cadena están sienpre mirando el último caracter. Estás poneindo car[20] en vez de car

ok pero no me estás diciendo especificamente en que parte del código, estoy usando es cad[20] no car[20] :p y entonces para que no miren siempre al ultimo caracter tendría que poner cad[1] cierto?
si pones cad[20] miras el último caracter y si pones cad[1] el segundo (ya que empieza por 0). Si pones cad como es dentro del for cada vez que incrementa la i adelantas un caracter.
Título: Re:Ayuda con C contar apariciones de una letra en una cadena
Publicado por: cipos en Abril 08, 2013, 06:56:12 am
 A ver, creo que como primera medida deberías leer un poco (más bien mucho) sobre arrays, me da la sensación que no comprendes algunos conceptos del tema.

 Dicho esto, te comento, más bien te pregunto:

 
Código: [Seleccionar]
for(i= 0 ; i<= cad[20] ; i++){
        if(cad[20] == let){
            rep= 1;
            }
           
            else if(rep != 1 && cad[20] == let){
            rep= rep +1;
            }
           
            else if(cad[20] == (char) 46){
                rep= rep;
                }
    }

  La comparación de parada en el for la haces con cad[20], entiendes que estas comparando el índice con lo que contiene el el arreglo en la posición 20?.  Además de que estas intentando acceder a una posición que esta fuera del rango de tu declaración. El último elemento del array es el cad[19] (empieza en 0, por esto es uno menos que la cantidad de elementos). Por lo que el compilador como mínimo te debería dar una advertencia...

 Luego haces la comparación de cad[20] == "e" (más allá del error que implica hacer eso, que es por que reitero deberías leer sobre arrays). Si la comparación devuelve True haces que rep valga 1.

 Obviando el error de la comparación (y suponiendo que compares lo que tengas que comparar) rep no va a valer más de 1, ya que cada vez que encuentre coincidencias haces que valga 1, en lugar de incrementar el contador (rep en este caso).

 Por qué dices que si rep != 1 y además el carácter (insisto obviando el error y suponiendo que querías hacer eso) que comparas es igual a 'e' que le sume uno a rep?.
 Y el último if es el más extraño de todos, por qué no pones un continue; en lugar de hacer rep = rep?. Más allá de que no tenga sentido ahí hacer un continue (o hacer un rep = rep).

 No sigo marcando errores en ese de código por que creo que no tiene sentido. Yo que tú me pondría a leer de nuevo por que estas bastante perdido. Ese bucle hace cualquier cosa menos contar la cantidad de apariciones de la letra 'e'.

 No quiero sonar agresivo, te lo digo de corazón. Relee (si ya lo has echo, cosa que dudo; si no lee) a conciencia, arreglos y capaz se te aclare un poco el panorama para cómo resolver este problema.

 Saludos!.

EDITO:

 El compilador no da advertencias si accedes a un elemento fuera del rango definido (o al menos no es obligatorio que las de). El tema es que en esa posición de memoria hay basura, lo que generaría un resultado imprevisible. Lo aclaro por que dí a entender que el compilador daría una advertencia o un error y eso no es cierto.
Título: Re:Ayuda con C contar apariciones de una letra en una cadena
Publicado por: r1ghtz0 en Abril 09, 2013, 02:17:18 am
Lo que pasa es que este ejercicio debería hacerse sin arreglos, esa es la razón. Estoy repasando un manual de lenguaje C y por donde voy no han tocado el tema de arrays, había un ejercicio que hice donde te pedían que mostraras el numero mayor y menor de una secuencia de digitos inctroducidas por el usuario, en este ejercicio que te comento era más facil usar lo arreglos claro, pero como todabía no llegaba a la parte de arrays me propuse hacerlo sin arrays y con un poco de ayuda me salio bien. Como vi que ese me salio bien entonces suponía que en este igualmente se podría hacer sin arrrays y tienes razón, me falta leer sobre arrays.

Código: [Seleccionar]
#include <stdio.h>
#include <math.h>
#include <string.h>

int main(int argc, char **argv)
{
int rep, i;
char cad[20], let;
let= 'e';

printf("Ingrese una cadena de caracteres: ");
scanf("%s", cad);

for(i= 0 ; i<=cad[i] ; i++){
if(cad[i] == let){
rep++;
}
}
printf("\nLa letra 'e' aparece %d veces", rep-1);

return 0;
}

Acá les dejo mis version del ejercicio y gracias a todos por su ayuda, realmente lo quería hacer sin arrays pero bueno... :p creo que no tiene manera de hacerlo. Puedes carrar JAG
Título: Re:Ayuda con C contar apariciones de una letra en una cadena
Publicado por: elpre en Abril 09, 2013, 02:37:18 am
Antes de cerrar una preguntilla que tiene que ver con el tema y no ya que acabo de comprobarlo ahora mismo.
He compilado el programa, tanto el de JAG como el r1ghtz0 y acabo de fijarme que cuando introduzco la frase al dar enter se cierra la aplicación. He probado a poner getchar() al final para forzar en enter y me pasa lo mismo. Para arreglarlo al pedir la frase en vez de con scanf lo he hecho con gets y ahora el de JAG sí funciona, el r1ghtz0 me da resultados raros.
Por no abrir otro tema, será cosa del compilador?? utilizo dev-c++ version 4.9.9.2
Título: Re:Ayuda con C contar apariciones de una letra en una cadena
Publicado por: r1ghtz0 en Abril 09, 2013, 02:43:43 am
Antes de cerrar una preguntilla que tiene que ver con el tema y no ya que acabo de comprobarlo ahora mismo.
He compilado el programa, tanto el de JAG como el r1ghtz0 y acabo de fijarme que cuando introduzco la frase al dar enter se cierra la aplicación. He probado a poner getchar() al final para forzar en enter y me pasa lo mismo. Para arreglarlo al pedir la frase en vez de con scanf lo he hecho con gets y ahora el de JAG sí funciona, el r1ghtz0 me da resultados raros.
Por no abrir otro tema, será cosa del compilador?? utilizo dev-c++ version 4.9.9.2

De verdad a mi si me funciona el hice yo, ingreso 10 'e' y me da como resultado que la 'e' se repite 10 veces. Es posible que sea el compilador como dices, yo no uso wind, uso linux mint y compilo con Geany.
Título: Re:Ayuda con C contar apariciones de una letra en una cadena
Publicado por: cipos en Abril 09, 2013, 02:45:57 am
 Ahí esta un poco más orientado el problema. Aunque sigo viendo errores.

Código: [Seleccionar]
    for(i= 0 ; i<=cad[i] ; i++){

 La condición de parada debe ser "i < (tamaño de la cadena)". estas haciendo "i <= (que el elemento de la posición i-ésima). Lo cuál no tiene sentido.

 Además (de esto no estoy seguro, hace un tiempo que no toco C, corrijanme si me equivoco) la forma en la que almacenas la cadena la variable cad no es conveniente. Prueba en tipear una cadena con espacios, por ejemplo:

 "e e e e"

 Si no me equivoco eso devolvería 1. Ya que "cuenta" hasta el primer espacio. Para "arreglar" eso yo cambiaría esta parte del código:

Código: [Seleccionar]
printf("Ingrese una cadena de caracteres: ");
    scanf("%s", cad);
 
Por:

Código: [Seleccionar]
printf("Ingrese una cadena de caracteras: ");
scanf(" %[^\n]", cad);


 Saludos!.

EDITO:

He compilado el programa, tanto el de JAG como el r1ghtz0 y acabo de fijarme que cuando introduzco la frase al dar enter se cierra la aplicación. He probado a poner getchar() al final para forzar en enter y me pasa lo mismo.

 Prueba de correr la aplicación desde simbolo de sistema de Windows, así no se te va a cerrar la ventana.

 Y los resultados raros se deben a que en el for la condición de parada está mal. Arriba en mi respuesta le comente sobre esto a r1ghtz0

Título: Re:Ayuda con C contar apariciones de una letra en una cadena
Publicado por: JAG en Abril 09, 2013, 10:04:59 am
También pueden deberse los resultados raros a que rep que es el contador no lo inicializas a 0. Como apunta cipos sigue habiendo errores en el que hiciste y también es cierto lo de que cuenta hasta el primer espacio, buen apunte cipos!
En cuanto a lo que comentas elpre, es que yo lo compilé desde la consola de linux... entonces no se me cierra xD puedes poner lo siguiente y hasta que no pulses enter no se saldrá:
while(getchar()!='\n');

Saludos!!
Título: Re:Ayuda con C contar apariciones de una letra en una cadena
Publicado por: elpre en Abril 09, 2013, 04:39:02 pm
Ok, voy a probar con linux y también con el while. De todas formas pensaba que con solo poner getchar() era suficiente para eso. Aún así tiene que ser el compilador seguro porque ha sido poner gets(cad) y funcionar, buscaré en internet a ver si pone algo al respecto

Edito: lo de los espacios es verdad con scanf, si se utiliza gets se pueden poner espacios y los cuenta. Con linux al hacerlo con consola no se me sale (evidente) pero me ha surgido una pequeña duda y es que he modificado un poco el programa y en vez de ponerle la letra al declarar la variable, hago que se pida y resulta que si hago:
Código: [Seleccionar]
printf("\nIntroduce cadena: ");
 scanf("%s",cadena);
 printf("\nIntroduce letra a buscar: ");
 scanf("%c",&letra);
En este caso la instrucción de "introduce letra a buscar me la salta (me la imprime en pantalla pero no me deja poner la letra. En cambio si hago
Código: [Seleccionar]
printf("\nIntroduce cadena: ");
 gets(cadena);
 printf("\nIntroduce letra a buscar: ");
 scanf("%c",&letra);
Con este caso todo perfecto
Título: Re:Ayuda con C contar apariciones de una letra en una cadena
Publicado por: k133 en Abril 12, 2013, 10:29:39 pm
@elpre
Creo que eso te pasa por que no limpias el buffer de entrada, revisa:
http://foro.hackxcrack.net/forum/index.php?topic=17849.0