Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: NOB2014 en 5 Agosto 2014, 19:35 pm



Título: Sustituir cada palabra de 4 letras con asteriscos(lenguaje c)
Publicado por: NOB2014 en 5 Agosto 2014, 19:35 pm
Hola a todos.
Me pase con este tema unas cuantas horas y hasta aquí llegue, espero que me puedan ayudar a resolverlo.-

En primer lugar les pongo el enunciado.
(http://i59.tinypic.com/124tys4.png)

Lo que llevo hecho es lo siguiente.

Código
  1. #include <stdio.h>
  2. #include <string.h>
  3.  
  4. int main(void){
  5. char tempFrase[] = "La casa de Juan es de color azul", *token, frase[32];
  6. int ocurrencias=0;
  7.  
  8. strcpy(frase, tempFrase);
  9.  
  10. token = strtok(tempFrase," ");
  11. while (token != NULL){
  12. printf("\n En la direccion %p se encuentra la palabra...: %s\n", token ,token);
  13. (strlen(token) == 4) ? ocurrencias++ : ocurrencias;
  14. token = strtok(NULL," ");
  15. }
  16.  
  17. printf("\n La frase \"%s\" contiene %d palabras de 4 letras\n\n", frase, ocurrencias);
  18.  
  19. return 0;
  20. }
  21.  
  22.  
  23.  
  24. /*
  25. #include <stdio.h>
  26. #include <string.h>
  27.  
  28. #define MAX_FRASES 5
  29. #define MAX_LONGITUD 30
  30.  
  31. void verificaIngreso(char frases[][MAX_LONGITUD], int i);
  32.  
  33. int main(void){
  34. char frases[MAX_FRASES][MAX_LONGITUD];
  35. int i=0, j=0, ocurrencias=0, com=0, fin=0;
  36.  
  37. for(; i<MAX_FRASES; i++){
  38. printf("\n Ingrece frase[%d]...:", i+1);
  39. fgets(frases[i], MAX_LONGITUD, stdin);
  40. verificaIngreso(frases, i);
  41. }
  42.  
  43. for(i=0; i<MAX_FRASES; i++){
  44. printf("\n La frase[%d] tiene una longitud de %d caracteres", i+1,  strlen(frases[i]));
  45. }
  46.  
  47. for(i=0; i<MAX_FRASES; i++){
  48. for(j=0; frases[i][j]; j++){
  49. if(frases[i][j] == 32)
  50. com = frases[j]
  51.  
  52. }
  53. }
  54.  
  55. printf("\n %d", espacios);
  56. printf("\n\n");
  57. return 0;
  58. }
  59.  
  60. void verificaIngreso(char frases[][MAX_LONGITUD], int i){
  61. char *p=NULL;
  62. unsigned int ch=0;
  63.  
  64. if((p=strchr(frases[i], '\n'))!=0){
  65. *p='\0';
  66. }
  67. else{
  68. while((ch = getchar()) !='\n' && ch!=EOF);
  69. }
  70.  
  71. }*/

Lo que no puedo saber es ¿Qué referencia debo utilizar para acceder a la variable frase y sustituir todas las palabras de 4 letras con asteriscos ?.- 
 
Saludos y desde ya muchas gracias por el tiempo.-
Daniel


Título: Re: Sustituir cada palabra de 4 letras con asteriscos(lenguaje c)
Publicado por: leosansan en 5 Agosto 2014, 21:47 pm
Teniendo en cuenta que pueden haber varios espacios en blanco seguidos y haciendo el bestia, sin usar las funciones propias para estos efectos, propongo:

Código
  1. ********************************************************
  2.  
  3. char frase [  ] = "1234   789 1234 321  9876 56 " ;
  4.  for ( i = 0 ; frase [ i ] ; i++  ) {
  5.    if ( frase [ i ] != ' ' )
  6.      j++ ;
  7.    if ( frase [ i ] == ' ' ) {
  8.      if ( j == 4 ){
  9.        cont++ ;
  10.        for ( k = i - 1 ; k >= i - 4  ; k-- )
  11.          frase [ k ] = '*' ;
  12.      }
  13.  
  14.    j = 0 ;
  15.    }
  16.  }
  17.  printf ( "\n\nLa frase final es: %s" , frase ) ;
  18.  printf ( "\n\nY contiene %d palabras de cuatro letras.\n\n" , cont ) ;
  19.  
  20. *******************************************************
  21.  

¡¡¡¡ Saluditos! ..... !!!!


(http://st.forocoches.com/foro/images/smilies/simba1.gif)


Título: Re: Sustituir cada palabra de 4 letras con asteriscos(lenguaje c)
Publicado por: NOB2014 en 6 Agosto 2014, 16:17 pm
Hola Leo.
Gracias “viejo” amigo por responder, corrí tú código y me dio el mismo error que a la mayoría, si la última palabra tiene 4 letras y no tiene un espacio entre la última letra y el ‘\0’ no la sustituye.-
Bueno dejo mi versión.-   

Código
  1. #include <stdio.h>
  2.  
  3. int main(void){
  4. char s1[] = "hola Daniel como estas? Soy Pino1952 pero tambien Daniel o Dany chao";
  5. int i=0, cont=0, cant=0;
  6.  
  7. printf("\n cadena original....: %s\n", s1);
  8. for(; s1[i]; i++){
  9. cont++;
  10. if(s1[i] == ' '){
  11. if(cont==5){
  12. for(cont=i-4; cont <i; cont++){
  13. s1[cont] = '*';
  14. }
  15. cant++;
  16. }
  17. cont=0;
  18. }
  19. }
  20. if(cont==4){
  21. for(cont=i-4; cont <i; cont++){
  22. s1[cont] = '*';
  23. }
  24. cant++;
  25. }
  26.  
  27. printf("\n Cadena reemplazada.: %s\n", s1);
  28. printf("\n Se han sustituido un total de %d palabras.\n\n", cant);
  29.  
  30. return 0;
  31. }

Saludos.
Daniel


Título: Re: Sustituir cada palabra de 4 letras con asteriscos(lenguaje c)
Publicado por: leosansan en 6 Agosto 2014, 19:19 pm
Hola Leo.
Gracias “viejo” amigo por responder, corrí tú código y me dio el mismo error que a la mayoría, si la última palabra tiene 4 letras y no tiene un espacio entre la última letra y el ‘\0’ no la sustituye.-
Bueno dejo mi versión.-  

Saludos.
Daniel


¡¡¡ Un placer volver a verte por aquí !!!, amigo Daniel.

Ya ves que las prisas y el no testear a fondo un código tiene a veces esas consecuencias.

En realidad, y creo que como bien has observado, faltaba "la última comprobación", los cuatro últimos caracteres. Paso mi código con esa corrección:

Código
  1. ************************************************
  2.  char frase [  ] = "1234   789 1234 321  9876 5678" ;
  3.  frase [ strlen ( frase ) ] =' ' ;
  4.  for ( i = 0 ; i < strlen( frase ) - 1 ; i++  ) {
  5.    if ( frase [ i ] != ' ' )
  6.      j++ ;
  7.    else if ( frase [ i ] == ' '  ) {
  8.      if ( j == 4 ){
  9.        cont++ ;
  10.        for ( k = i - 1 ; k >= i - 4  ; k-- )
  11.          frase [ k ] = '*' ;
  12.      }
  13.    j = 0 ;
  14.    }
  15.  }
  16.  frase [ i ] = '\0' ;
  17.  printf ( "\n\nLa frase final es: %s" , frase ) ;
  18.  printf ( "\n\nY contiene %d palabras de cuatro letras.\n\n" , cont ) ;
  19. *******************************************************

Y lo dicho, un placer el volver a encontrarte, y espero que sea más a menudo ¡¡¡Campeón!!!!. ;) ;) ;)

EDITADO para hacer uso de strlen y abreviar.

¡¡¡¡ Saluditos! ..... !!!!


(http://st.forocoches.com/foro/images/smilies/aaaaa.gif)


Título: Re: Sustituir cada palabra de 4 letras con asteriscos(lenguaje c)
Publicado por: Blaster en 6 Agosto 2014, 20:58 pm
Otra forma, usando la función strchr:

Editado:

Código
  1. char s1[] = " 1234 789  1234 321   9876 5678 ";
  2.  
  3. for( i = 0, j = 0; s1[ i ] != '\0'; i++, j++ )
  4. {
  5.     if( strchr( " \0", s1[i + 1] ) && j == 3 )
  6.     {
  7.        for( j = i - 3; j <= i; j++ )
  8.             s1[ j ] = '*';
  9.        cant++, j = 0;
  10.     }
  11.     s1[i + 1] == ' ' ? (j = -2) : ( s1[ i ] == ' ' && i == 0 )
  12.     ? (j = -1) : (j = j);
  13. }
  14. printf("\n Cadena reemplazada.: %s\n", s1);
  15. printf("\n Se han sustituido un total de %d palabras.\n\n", cant);
  16.  

Saludos


Título: Re: Sustituir cada palabra de 4 letras con asteriscos(lenguaje c)
Publicado por: leosansan en 7 Agosto 2014, 00:59 am
Otra forma, usando la función strchr:
..............................
Saludos

¿Pero no quedamos en que íbamos a implementar nuestras propias funciones?  :laugh:

Es broma.

Está muy bien pero a mí me falla, y ya lo digo con miedo a equivocarme, porque si el primer espacio es un espace  y la primera cadena es de cuatro no la cambia por asteriscos:

Código
  1.  
  2. Cadena original.:  1234   789 1234 321  9876 5678
  3.  
  4. Cadena reemplazada.:  1234   789 **** 321  **** ****
  5.  
  6. Se han sustituido un total de 3 palabras.
  7.  
  8. Process returned 0 (0x0)   execution time : 0.025 s
  9. Press any key to continue.
  10.  


¡¡¡¡ Saluditos! ..... !!!!


(http://st.forocoches.com/foro/images/smilies/simba2.gif)


Título: Re: Sustituir cada palabra de 4 letras con asteriscos(lenguaje c)
Publicado por: Blaster en 7 Agosto 2014, 04:28 am
Está muy bien pero a mí me falla, y ya lo digo con miedo a equivocarme, porque si el primer espacio es un espace  y la primera cadena es de cuatro no la cambia por asteriscos:

Inconveniente solventado ahora va de maravilla edite el código de arriba 

Saludos


Título: Re: Sustituir cada palabra de 4 letras con asteriscos(lenguaje c)
Publicado por: leosansan en 7 Agosto 2014, 16:34 pm
Inconveniente solventado ahora va de maravilla edite el código de arriba  

Saludos

Perfecto, ahora va como la seda.  ;-) ;-)

Y con una línea más a cambio de no usar función alguna:

Código
  1. ***************************************************
  2.  
  3.  char frase [ ] = "1234  23789 1234 321  9876 5679";
  4.  for( i = 0;  frase [ i ]; i++  ){
  5.    iNoEspacio = ( frase [ i ] !=  ' ' ) ?  iNoEspacio + 1 : 0 ;
  6.    if ( iNoEspacio == 4  && ( frase [ i+1 ] ==  ' ' || frase [ i+1 ]==  '\0') ) {
  7.      for ( k = i  ; k >= i - 3  ; k-- ){
  8.        frase [ k ] = '*'  ;
  9.      }
  10.    iNoEspacio = 0 , cont++ ;
  11.    }
  12.  }
  13.  
  14. **********************************************************

Espero que esto nos sirva a todos  para que ver que soluciones "haberlas haylas " y que tan sólo es cuestión del momento que salga una a bote pronto pero hay que analizar las distintas opciones en busca de la más eficiente.  ;)

¡¡¡¡ Saluditos! ..... !!!!


(http://st.forocoches.com/foro/images/smilies/simba1.gif)


Título: Re: Sustituir cada palabra de 4 letras con asteriscos(lenguaje c)
Publicado por: Blaster en 7 Agosto 2014, 16:51 pm
Y con una línea más a cambio de no usar función alguna:

Va bien pero no tiene en cuenta si la ultima palabra es de cuatro caracteres y no tiene un espacio entre el ultimo carácter y el carácter nulo

Saludos


Título: Re: Sustituir cada palabra de 4 letras con asteriscos(lenguaje c)
Publicado por: leosansan en 7 Agosto 2014, 17:21 pm
Va bien pero no tiene en cuenta si la ultima palabra es de cuatro caracteres y no tiene un espacio entre el ultimo carácter y el carácter nulo

Saludos
Pues a corregirlo.  ;)

EDITO:

Es que ese caracter nulo  ;D:

Edité el mensaje anterior, pero lo que modifiqué fue la línea:

Código
  1. if ( iNoEspacio == 4  && ( frase [ i+1 ] ==  ' ' || frase [ i+1 ]==  '\0') )

para tener en cuenta al nulo.  ;-)

(http://st.forocoches.com/foro/images/smilies/simba1.gif)


Título: Re: Sustituir cada palabra de 4 letras con asteriscos(lenguaje c)
Publicado por: rir3760 en 7 Agosto 2014, 19:01 pm
Es que ese caracter nulo  ;D:

Edité el mensaje anterior, pero lo que modifiqué fue la línea:

Código
  1. if ( iNoEspacio == 4  && ( frase [ i+1 ] ==  ' ' || frase [ i+1 ]==  '\0') )

para tener en cuenta al nulo.  ;-)
Es mejor mantenerse con la versión con centinela ya que a cambio de dos asignaciones fuera del bucle te ahorras la comparación dentro de este.

Otra alternativa consiste en utilizar la función strcspn para encontrar el siguiente carácter igual a ' ' o '\0' y la función memset para imprimir los cuatro espacios (los prototipos de ambas en <string.h>).

Un saludo


Título: Re: Sustituir cada palabra de 4 letras con asteriscos(lenguaje c)
Publicado por: Blaster en 7 Agosto 2014, 21:31 pm
Otra alternativa consiste en utilizar la función strcspn para encontrar el siguiente carácter igual a ' ' o '\0' y la función memset para imprimir los cuatro espacios (los prototipos de ambas en <string.h>).

Me gusto la idea de rir3760 la implemente de esta manera:

Código
  1. char s1[] = " 1234 78   12345 321  9876 5678 ";
  2. int pos = 0;
  3.  
  4. for (i = 0; s1[ i ] != '\0'; i += pos + 1)
  5.   if (((pos = strcspn( s1 + i, " " )) == 4 &&
  6.       s1[ i - 1 ] == ' ') || (s1[4] == ' ' && i == 0))
  7.     memset( s1 + i, '*', 4 ), cont++;
  8.  
  9. printf("\n Cadena reemplazada.: %s\n", s1);
  10. printf("\n Se han sustituido un total de %d palabras.\n\n", cont);
  11.  

Saludos


Título: Re: Sustituir cada palabra de 4 letras con asteriscos(lenguaje c)
Publicado por: leosansan en 7 Agosto 2014, 22:46 pm
Me gusto la idea de rir3760 la implemente de esta manera:
......................................................................
  
Código
  1. else if (s1[ i + 4 ] == ' ' && i == 0)
  2.      memset( s1 + i, '*', 4 ),
  3.      cont++;
..................................................

......................................................................

Sólo que el else-if está exclusivamente para el la posible primera palabra y podría ser más propio:

Código
  1. else if (s1[ 4 ] == ' ' )
  2.      memset( s1 + 0, '*', 4 ),cont++;

Peo al César lo que es del César, lo has bordado.  ;)

¡¡¡¡ Saluditos! ..... !!!!


(http://st.forocoches.com/foro/images/smilies/simba2.gif)


Título: Re: Sustituir cada palabra de 4 letras con asteriscos(lenguaje c)
Publicado por: Blaster en 7 Agosto 2014, 22:55 pm
Sólo que el else-if está exclusivamente para el la posible primera palabra y podría ser más propio:

Es cierto leosansan no me había fijado, gracias por la observación  ;)

Saludos


Título: Re: Sustituir cada palabra de 4 letras con asteriscos(lenguaje c)
Publicado por: NOB2014 en 8 Agosto 2014, 04:38 am
Hola a todos.
Me gusta esta triada, rir3760 la idea, Blaster la materializa y Leo el vigilador, observador, corregidor, muy interesante el código de Blaster, realmente no creo que se pueda hacer con menos líneas y como soy un apasionado de los códigos concisos, muchos aplausos para los tres.-  ;-) ;-) ;-)
Yo tengo mi última versión pero ante esto realmente da vergüenza, el lacayo se rinde a vuestros pies.- :-X
Después de esto tengo que implementar un programa con números mágicos, si no lo logro por mi cuenta les pediré ayuda.-     

Saludos y un gran abrazo.
Daniel.


Título: Re: Sustituir cada palabra de 4 letras con asteriscos(lenguaje c)
Publicado por: leosansan en 8 Agosto 2014, 05:59 am
Es mejor mantenerse con la versión con centinela ya que a cambio de dos asignaciones fuera del bucle te ahorras la comparación dentro de este.
............................................................................................

Estaré "espeso" pero no veo que me salga del array, en todo caso veo que llego al caracter nulo pero no más allá.


Otra alternativa consiste en utilizar la función strcspn para encontrar el siguiente carácter igual a ' ' o '\0' y la función memset para imprimir los cuatro espacios (los prototipos de ambas en <string.h>).


Por cosa como esas es por lo que te echaba de menos últimamente "maestro".  ;-)

Como Blaster se me adelantó, mi propuesta es una "mezcla, uso memset para copiar los asteriscos y sigo usando mi propia "strcspn" y con el mismo y escueto número de líneas:

Código
  1. ***************************************************
  2.  
  3. char frase[] = "123456  23789 1234 3213  986   5679";
  4.  
  5.  for( i = 0 ;  frase [ i ] ; i++  )
  6.    if ( ( iNoEspacio = ( frase [ i ] !=  ' ' ) ?  iNoEspacio + 1 : 0 ) == 4  && ( frase [ i + 1 ] ==  ' ' || frase [ i + 1 ] ==  '\0') )
  7.      memset ( frase + i - 3 , '*' , 4 ) , cont++ ;
  8.  
  9.  printf( "\n    Cadena final.: %s\n\nY contiene %d palabras de cuatro letras.\n\n\n" , frase, cont) ;
  10.  
  11. **********************************************************

Hola a todos.
Me gusta esta triada, rir3760 la idea, Blaster la materializa y Leo el vigilador, observador, corregidor
..........................................................................................

Gracias a tí Daniel por querer compartir conocimientos y, como no, a Blaster y rir3760 por los "bellos" aportes que han realizado y el espíritu de sana competencia que nos lleva a enriquecernos a todos, al menos intelectualmente.

Y sí, creo que entre todos los usuarios de este foro formamos un buen equipo, y eso que he echado de menos a eferion y vangdop, etc.... y al ya lejano amchacon. Esto último sí que me duele, espero que se anime y vuelva por este foro.

..........................................................................................
Después de esto tengo que implementar un programa con números mágicos, si no lo logro por mi cuenta les pediré ayuda.-     
............................................................................................

Eso me alegra de manera especial ya que yo soy más de números que, como este tema, de letras. Esperaremos impacientes tus aportes y/o dudas al respecto.

Un fuerte abrazo, campeón.

¡¡¡¡ Saluditos! ..... !!!!


(http://st.forocoches.com/foro/images/smilies/aaaaa.gif)


Título: Re: Sustituir cada palabra de 4 letras con asteriscos(lenguaje c)
Publicado por: Blaster en 8 Agosto 2014, 16:14 pm
Nueva versión la deje de la siguiente manera:

Código
  1. char s1[] = " 1234 78   12345 321  9876 5678 ";
  2. int pos = 0;
  3.  
  4. for (i = 0; s1[ i ] != '\0'; i += pos + 1)
  5.   if ((pos = strcspn(s1 + i, " ")) == 4 && strchr(" \0", s1[i+pos]))
  6.      memset( s1 + i, '*', 4 ), cont ++;
  7.  
  8. printf("\n Cadena reemplazada.: %s\n", s1);
  9. printf("\n Se han sustituido un total de %d palabras.\n\n", cont);

No me gustaba lo de restarle uno  ;)

EDITO:

Creo es mejor conservar la versión anterior, ya que encontré que esta es
propensa a hacer comparaciones fuera del buffer al pasarle una cadena como esta
"2510 2"

REEDITÓ:

Ahora va perfecto

Saludos