Que hago mal? compilar pero no ejecuta bien

Iniciado por roser24, 5 Mayo 2010, 20:46 PM

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

roser24

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


/*7. Crear una función a la que se le pasará una cadena de caracteres de cualquier
longitud y retornará el número
de vocales distintas que la forman. Genera un programa principal en el se introduzca
  una cadena que se validará para que incluya todas las vocales.*/
  #include<stdio.h>
  #include<string.h>
  #include<stdlib.h>
  void f_vocales(char *,int);
  void f_visu(char *,int);
  int main(){

  int l,aux;

printf("Introduce la longitud de la cadena:\n");
scanf("%d",&l);
char *cad=(char *)(malloc(sizeof(char)*l));


do{
printf("Introduce la cadena:\n");
scanf("%s",cad);
//gets(cad);
aux=strlen(cad);
}while(aux<0 || aux>l);

f_vocales(cad,aux);
f_visu(cad,aux);
free(cad);
return 0;
}

void f_vocales(char *cadena,int size){
  int i=0,cont=0;
  for(i=0;*(cadena+i)!='\0'&& i<size;i++){
  if(*(cadena+i)=='a'){
  cont++;
}
}
printf("el numero de veces que aparece a es:%d",cont);
}

void f_visu(char *cadena,int size){
int i=0;
for(i=0;*(cadena+i)!='\0'&&i<size;i++){
printf("%s",*(cadena+i));
}
}

Akai

el problema está aqui:

void f_visu(char *cadena,int size){
int i=0;
for(i=0;*(cadena+i)!='\0'&&i<size;i++){
printf("%s",*(cadena+i));
}
}


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:

void f_visu(char *cadena){
printf("%s",cadena);/* imprimimos toda la cadena de una sola vez*/
}

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:

void f_visu(char *cadena,int size){
int i=0;
for(i=0;*(cadena+i)!='\0'&&i<size;i++){
printf("%c",*(cadena+i)); /*imprimimos caracter a carácter*/
}
}

roser24

#2
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..
/*7. Crear una función a la que se le pasará una cadena de caracteres de cualquier
longitud y retornará el número
de vocales distintas que la forman. Genera un programa principal en el se introduzca
  una cadena que se validará para que incluya todas las vocales.*/
  #include<stdio.h>
  #include<string.h>
  #include<stdlib.h>
  void f_vocales(char *,int);
  void f_visu(char *);
  int main(){

  int l,aux;

printf("Introduce la longitud de la cadena:\n");
scanf("%d",&l);
char *cad=(char *)(malloc(sizeof(char)*l));


do{
printf("Introduce la cadena:\n");
//scanf("%s",cad);
gets(cad);
aux=strlen(cad);
}while(aux<0 || aux>l);

f_vocales(cad,aux);
f_visu(cad);
free(cad);
return 0;
}

void f_vocales(char *cadena,int size){
  int i=0,cont=0;
  for(i=0;i<size;i++){
  if(*(cadena+i)=='a'){
  cont++;
}
}
printf("el numero de veces que aparece a es:%d",cont);
}

void f_visu(char *cadena){
printf("\nla cadena introducida fue %s",cadena);
}

roser24

 :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?

Akai

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:

scanf("%d",&l);
char *cad=(char *)(malloc(sizeof(char)*l));
gets(cad);

leogtz

Procura ponerle nombres significativos a las variables, ¿qué es eso de "l"?

Básate en esto:

#include <stdio.h>
#include <stdlib.h>
void contarA(char *cadena)
{
    unsigned int contador = 0, i;
    for(i = 0; *(cadena + i); i++)
    if(*(cadena + i) == 'a')
    contador++;
    printf("La letra \"a\" aparece %u veces.", contador);
}
void ver(char *cadena)
{
    putchar('\n');
    unsigned int i = 0;
    while(*(cadena + i))
    putchar(*(cadena + i++));
    putchar('\n');
}
int main(void)
{
    unsigned int n;
    do
    {
        printf("Longitud de la cadena : ");
        setbuf(stdin, NULL);
    } while(scanf("%u", &n) != 1);
    while(getchar() != '\n');
    char *cadena = (char *)malloc(sizeof(char) * n);
    printf("Cadena : ");
    fgets(cadena, n, stdin);
    contarA(cadena);
    ver(cadena);
    return 0;
}
Código (perl) [Seleccionar]

(( 1 / 0 )) &> /dev/null || {
echo -e "stderrrrrrrrrrrrrrrrrrr";
}

http://leonardogtzr.wordpress.com/
leogutierrezramirez@gmail.com

roser24

hola,bueno vereis ya corregi el codigo del programa,añadiendo una "basura".

#include<stdio.h>
  #include<string.h>
  #include<stdlib.h>
  void f_vocales(char *,int);
  void f_visu(char *);
  int main(){

  int l,aux;
  char basura;

printf("Introduce la longitud de la cadena:\n");
scanf("%d",&l);
scanf("%c",&basura);
char *cad=(char *)(malloc(sizeof(char)*l));


do{
printf("Introduce la cadena:");

gets(cad);
aux=strlen(cad);
}while(aux<0 || aux>l);

f_vocales(cad,aux);
f_visu(cad);
free(cad);
return 0;
}

void f_vocales(char *cadena,int size){
  int i=0,cont=0;
  for(i=0;i<size;i++){
  if(*(cadena+i)=='a'){
  cont++;
}
}
printf("el numero de veces que aparece a es:%d\n",cont);
}

void f_visu(char *cadena){
printf("la cadena introducida fue %s",cadena);
}


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 =),

cgvwzq

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.
Some stuff:

  • www.a] parsed as www.a]
  • Bypass elhacker's img filter with ALT attribute!
  • ¿Para cuándo SQLi I y II? WZ



roser24

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?

Littlehorse

#9
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!
An expert is a man who has made all the mistakes which can be made, in a very narrow field.