Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: roser24 en 5 Mayo 2010, 20:46 pm



Título: Que hago mal? compilar pero no ejecuta bien
Publicado por: roser24 en 5 Mayo 2010, 20:46 pm
Hola chicos,pues tal y como dice el titulo empeze a hacer el siguiente ejercicio no me da errores en la compilacion y ejecuta pero solo hasta cuando inserto la cadena.. probe  con gets con scanf para leerla pero sigue igual,una vez le doy intro me da un error y se cierra .. :(,por favor si podeis mirarlo y si veis los errores indicarmelo,de momento solo quise validar la letra A ..Salu2


Código
  1. /*7. Crear una función a la que se le pasará una cadena de caracteres de cualquier
  2. longitud y retornará el número
  3.  de vocales distintas que la forman. Genera un programa principal en el se introduzca
  4.   una cadena que se validará para que incluya todas las vocales.*/
  5.  #include<stdio.h>
  6.  #include<string.h>
  7.  #include<stdlib.h>
  8.  void f_vocales(char *,int);
  9.  void f_visu(char *,int);
  10.  int main(){
  11.  
  12.  int l,aux;
  13.  
  14. printf("Introduce la longitud de la cadena:\n");
  15. scanf("%d",&l);
  16. char *cad=(char *)(malloc(sizeof(char)*l));
  17.  
  18.  
  19. do{
  20. printf("Introduce la cadena:\n");
  21. scanf("%s",cad);
  22. //gets(cad);
  23. aux=strlen(cad);
  24. }while(aux<0 || aux>l);
  25.  
  26. f_vocales(cad,aux);
  27. f_visu(cad,aux);
  28. free(cad);
  29. return 0;
  30. }
  31.  
  32. void f_vocales(char *cadena,int size){
  33.  int i=0,cont=0;
  34.  for(i=0;*(cadena+i)!='\0'&& i<size;i++){
  35.  if(*(cadena+i)=='a'){
  36.  cont++;
  37. }
  38. }
  39. printf("el numero de veces que aparece a es:%d",cont);
  40. }
  41.  
  42. void f_visu(char *cadena,int size){
  43. int i=0;
  44. for(i=0;*(cadena+i)!='\0'&&i<size;i++){
  45. printf("%s",*(cadena+i));
  46. }
  47. }


Título: Re: Que hago mal? compilar pero no ejecuta bien
Publicado por: Akai en 5 Mayo 2010, 20:59 pm
el problema está aqui:

Código
  1. void f_visu(char *cadena,int size){
  2. int i=0;
  3. for(i=0;*(cadena+i)!='\0'&&i<size;i++){
  4. printf("%s",*(cadena+i));
  5. }
  6. }

Para imprimir una cadena con printf y %s no necesitas ir realizando printfs como si imprimiras carácter a carácter, %s indica que le pasas una cadena, y la imprimirá entera. Por tanto tienes dos opciones:

Código
  1. void f_visu(char *cadena){
  2. printf("%s",cadena);/* imprimimos toda la cadena de una sola vez*/
  3. }
Notese que no necesitamos el tamaño ni un contador en esta función.

o bien, una solución mas similar a la función que daba problemas:

Código
  1. void f_visu(char *cadena,int size){
  2. int i=0;
  3. for(i=0;*(cadena+i)!='\0'&&i<size;i++){
  4. printf("%c",*(cadena+i)); /*imprimimos caracter a carácter*/
  5. }
  6. }


Título: Re: Que hago mal? compilar pero no ejecuta bien
Publicado por: roser24 en 5 Mayo 2010, 21:15 pm
Hola Akai,gracias por tu ayuda,corregi mi codigo y ejecuta pero me cuenta y me muestra solo la primera parte de la cadena es decir hasta que encuentra un /0,
quite la condicion de /0 en el for de la funcion pero me sigue haciendo lo mismo al ejecutar.. :( probe tmb con gets(cad) pero me ejecuta  mal compilar si lo dejo con gets,.. estoy usando mal el gets?

pongo mi codigo actual..
Código
  1. /*7. Crear una función a la que se le pasará una cadena de caracteres de cualquier
  2. longitud y retornará el número
  3.  de vocales distintas que la forman. Genera un programa principal en el se introduzca
  4.   una cadena que se validará para que incluya todas las vocales.*/
  5.  #include<stdio.h>
  6.  #include<string.h>
  7.  #include<stdlib.h>
  8.  void f_vocales(char *,int);
  9.  void f_visu(char *);
  10.  int main(){
  11.  
  12.  int l,aux;
  13.  
  14. printf("Introduce la longitud de la cadena:\n");
  15. scanf("%d",&l);
  16. char *cad=(char *)(malloc(sizeof(char)*l));
  17.  
  18.  
  19. do{
  20. printf("Introduce la cadena:\n");
  21. //scanf("%s",cad);
  22. gets(cad);
  23. aux=strlen(cad);
  24. }while(aux<0 || aux>l);
  25.  
  26. f_vocales(cad,aux);
  27. f_visu(cad);
  28. free(cad);
  29. return 0;
  30. }
  31.  
  32. void f_vocales(char *cadena,int size){
  33.  int i=0,cont=0;
  34.  for(i=0;i<size;i++){
  35.  if(*(cadena+i)=='a'){
  36.  cont++;
  37. }
  38. }
  39. printf("el numero de veces que aparece a es:%d",cont);
  40. }
  41.  
  42. void f_visu(char *cadena){
  43. printf("\nla cadena introducida fue %s",cadena);
  44. }


Título: Re: Que hago mal? compilar pero no ejecuta bien
Publicado por: roser24 en 5 Mayo 2010, 21:23 pm
 :oLes va a parecer raro seguramente pero si quito el \n de un printf exactamente del de visualizar,.. me ejecuta bien el conteo y la visualizacion de la cadena..
como puede ser posible esto?


Título: Re: Que hago mal? compilar pero no ejecuta bien
Publicado por: Akai en 5 Mayo 2010, 21:34 pm
El problema, que no lo había pensado antes, es la "basura" que se queda por usar scanf, en concreto un \n de cuando pulsas la tecla enter para introducir el tamaño de la cadena. Y es lo que se come gets(cadena). Lo raro, es que te funcione si quitas un \n de un printf que nada tiene que ver con la entrada de datos. 

Lo que se me ocurre, es hacer un gets justo después del scanf, para limpiar el n residual, que luego es machacado por el siguiente gets(cadena). Aun así es una forma un tanto.. sucia de hacerlo, existiendo otras funciones que permiten una entrada mas "limpia" de datos, pero no las conozco.

el apaño temporal para el programa es:

Código
  1. scanf("%d",&l);
  2. char *cad=(char *)(malloc(sizeof(char)*l));
  3. gets(cad);


Título: Re: Que hago mal? compilar pero no ejecuta bien
Publicado por: leogtz en 5 Mayo 2010, 21:50 pm
Procura ponerle nombres significativos a las variables, ¿qué es eso de "l"?

Básate en esto:

Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. void contarA(char *cadena)
  4. {
  5.    unsigned int contador = 0, i;
  6.    for(i = 0; *(cadena + i); i++)
  7.    if(*(cadena + i) == 'a')
  8.    contador++;
  9.    printf("La letra \"a\" aparece %u veces.", contador);
  10. }
  11. void ver(char *cadena)
  12. {
  13.    putchar('\n');
  14.    unsigned int i = 0;
  15.    while(*(cadena + i))
  16.    putchar(*(cadena + i++));
  17.    putchar('\n');
  18. }
  19. int main(void)
  20. {
  21.    unsigned int n;
  22.    do
  23.    {
  24.        printf("Longitud de la cadena : ");
  25.        setbuf(stdin, NULL);
  26.    } while(scanf("%u", &n) != 1);
  27.    while(getchar() != '\n');
  28.    char *cadena = (char *)malloc(sizeof(char) * n);
  29.    printf("Cadena : ");
  30.    fgets(cadena, n, stdin);
  31.    contarA(cadena);
  32.    ver(cadena);
  33.    return 0;
  34. }
  35.  


Título: Re: Que hago mal? compilar pero no ejecuta bien
Publicado por: roser24 en 5 Mayo 2010, 22:19 pm
hola,bueno vereis ya corregi el codigo del programa,añadiendo una "basura".

Código
  1. #include<stdio.h>
  2.  #include<string.h>
  3.  #include<stdlib.h>
  4.  void f_vocales(char *,int);
  5.  void f_visu(char *);
  6.  int main(){
  7.  
  8.  int l,aux;
  9.  char basura;
  10.  
  11. printf("Introduce la longitud de la cadena:\n");
  12. scanf("%d",&l);
  13. scanf("%c",&basura);
  14. char *cad=(char *)(malloc(sizeof(char)*l));
  15.  
  16.  
  17. do{
  18. printf("Introduce la cadena:");
  19.  
  20. gets(cad);
  21. aux=strlen(cad);
  22. }while(aux<0 || aux>l);
  23.  
  24. f_vocales(cad,aux);
  25. f_visu(cad);
  26. free(cad);
  27. return 0;
  28. }
  29.  
  30. void f_vocales(char *cadena,int size){
  31.  int i=0,cont=0;
  32.  for(i=0;i<size;i++){
  33.  if(*(cadena+i)=='a'){
  34.  cont++;
  35. }
  36. }
  37. printf("el numero de veces que aparece a es:%d\n",cont);
  38. }
  39.  
  40. void f_visu(char *cadena){
  41. printf("la cadena introducida fue %s",cadena);
  42. }

Leo ,mmm hay varias lineas de tu codigo que no he visto nunca y por ello no lo entiendo..  por ejemplo lo de "setbuf(stdin, NULL); "de todas maneras gracias =),


Título: Re: Que hago mal? compilar pero no ejecuta bien
Publicado por: cgvwzq en 5 Mayo 2010, 22:30 pm
Lo del setbuf no lo he usado nunca, pero imagino que si no se usa buffer se imprime directamente en pantalla (sin necesidad de llenarlo o llegar a salto de linea o fin de fichero).

Y te recomiendo usar fgets en lugar de gets.


Título: Re: Que hago mal? compilar pero no ejecuta bien
Publicado por: roser24 en 5 Mayo 2010, 22:39 pm
okis,de verdad chicos que mil gracias por todos vuestros consejos apartir de ahora usar fgets  ;D
una cosilla el formato es fgets(cadena, n, stdin); n siempre sera el valor de i longitud sin contar el \0? o me olvido de los \0 con esta funcion?


Título: Re: Que hago mal? compilar pero no ejecuta bien
Publicado por: Littlehorse en 5 Mayo 2010, 22:43 pm
setbuf (http://www.cplusplus.com/reference/clibrary/cstdio/setbuf/)


Con fgets es conveniente leer n-1 del espacio total de la cadena, para asegurarte que luego puedes finalizar la cadena con '\0', aunque la función igualmente lo hace por vos, es conveniente asegurarse. En C, lamentablemente, nunca te tienes que olvidar de los '\0'.

Saludos!