[ Foro de C ]

Primer ejercicio Capítulo 5: Arrays y Estructuras.

18-May-2012 20:54
Pablo Rampa
46 Respuestas

 Necesito ayuda para llenar una tabla con números en forma interactiva en el primer ejercicio del Capítulo 5:
Un programa que pida al usuario 4 números, los memorice (utilizando una tabla), calcule su media aritmética y después muestre en pantalla la media y los datos tecleados.
 
#include
#include
main()
{
    int  n1, n2, n3, n4, media;
    char tabla[4]={n1, n2, n3, n4};
   
    printf("\n  Escriba  un  numero entero: ");
    gets(tabla);      
    n1=atoi(tabla);       /* Convierte la cadena s a un         entero.*/
    printf("\n  Escriba otro numero entero: ");
    gets(tabla);
    n2=atoi(tabla);
    printf("\n  Escriba otro numero entero: ");
    gets(tabla);
    n3=atoi(tabla);
    printf("\n  Escriba otro numero entero: ");
    gets(tabla);
    n4=atoi(tabla);
   
    media=(n1+n2+n3+n4)/4;
   
    printf("\n\n  La media es: %d", media);
    printf("\n ...y el contenido de la tabla es: %d %d %d %d ", n1, n2, n3, n4);
   
    getchar();
}
   
     ¿Cómo memorizar numeros en una tabla?
  De antemano, gracias por su atención.
 
  Un saludo cordial  y felicitaciones por el curso.


19-May-2012 02:10
Pablo Rampa



Lo he tratado de solucionar de esta forma. ¿Qué opinión se merece?
Gracias por su atención.

#include <stdio.h>
main()
{
    int i, media=1, suma=0, tabla[4];
    printf("\nEscriba 4 numeros\n\n");
    for (i=0; i<=3; i++)
         scanf("%d", &tabla[i]);
         for (i=0; i<=3; i++)
            {suma+=tabla[i];
            media=(suma/4);}
     printf("\n\n...La media es: %d", media);
     printf("\nLos numeros introducidos son: %d %d %d %d",   tabla[0], tabla[1], tabla[2], tabla[3]);
     getchar();
     getchar();
}


19-May-2012 02:34
Pablo Rampa


 O mejor así:

 #include <stdio.h>
main()
{
    int i, media=1, suma=0, tabla[4];
    printf("\nEscriba 4 numeros\n\n");
    for (i=0; i<=3; i++)
         scanf("%d", &tabla[i]);
         for (i=0; i<=3; i++)
              {suma+=tabla[i];
              media=(suma/4);}
         printf("\n\n...La media es: %d", media);
         printf("\nLos numeros introducidos son: ");
              for (i=0; i<=3; i++)
                   printf(" %d ", tabla[i]);    
              getchar();
              getchar();
                   
                   
}

  ...no sé si hay que hacerlo para números reales.
  Un saludo.


19-May-2012 04:11
Pablo Rampa

 
  O así:

 #include <stdio.h>
main()
{
    int i, x=1;
    float media=1, suma=0, tabla[x];
    printf("\n Cuantos numeros va a escribir?  ");
    scanf("%d", &x);
    printf(" Escriba los %d numeros \n\n", x);
    for (i=0; i<x; i++)
     
         scanf("%g", &tabla[i]);
         for (i=0; i<x; i++)
         
              {suma+=tabla[i];
              media=(suma/x);}
         printf("\n\n  ...La media es: %g", media);
         printf("\n\n Los numeros introducidos son: ");
              for (i=0; i<x; i++)
               
                    printf("%g   ", tabla[i]);    
              getchar();
              getchar();
                 
}
                                     .....Saludos.


19-May-2012 11:43
Nacho Cabanes (+83)

Está bien, Pablo. La última versión, que permite una cantidad arbitraria de números, es la más versátil.

El problema que tienen (todas ellas o casi) es que las tabulaciones son un poco anárquicas y la colocación de las llaves también, así que cuestan de leer.

Como "fallos reales": reservas espacio para un único elemento en el array, así que lo desbordas (algunos compiladores son tolerantes con eso y reservan espacio de más, pero otros no).

Quedaría un poco mejor así:

#include <stdio.h>
int main()
{
   int i;
   int cantidad;

   /* Pido la cantidad de números */
   printf("\n Cuantos numeros va a escribir?  ");
   scanf("%d", &cantidad);

   /* Pido los datos en sí */
   float tabla[cantidad];
   float suma=0;
   float media;
   printf(" Escriba los %d numeros \n\n", cantidad);
   for (i=0; i<cantidad; i++)
       scanf("%f", &tabla[i]);

   /* Calculo resultados */
   for (i=0; i<cantidad; i++)
       suma += tabla[i];

   media=suma / cantidad;

   /* Muestro resultados y datos */
   printf("\n\n  ...La media es: %f", media);
   printf("\n\n Los numeros introducidos son: ");
   for (i=0; i<cantidad; i++)
       printf("%f  ", tabla[i]);

   return 0;
}


19-May-2012 18:36
Pablo Rampa

Gracias por la corrección, estimado Nacho.

Este es el siguiente ejercicio.

 . Un programa que pida al usuario 5 números reales y luego    los muestre en el orden contrario al que se introdujeron.
       
#include <stdio.h>
main()
{
     int i;
     float reales[5];
     printf("\n Escriba  cinco numeros reales:\n\n");
     for (i=0; i<5; i++)
          scanf("%f", &reales[i]);
          printf("\n Los numeros, en orden inverso\n");
          printf(" al que fueron introducidos, son: ");
          for (i=4; i>=0; i--)
               printf("\n\n %.2f", reales[i]);
     getchar();
     getchar();
}
     
  Y aquí está el, último de los tres primeros ejercicios.    
Un cordial saludo.

. Un programa que pida al usuario 10 números enteros y calcule (y muestre) cuál es el mayor de ellos.

#include <stdio.h>

main()
{
      int i, mayor=0, enteros[10];
     
      printf("\n Escriba diez numeros enteros:\n\n");
      for (i=0; i<10; i++)
           scanf("%d", &enteros[i]);
           for (i=0; i<10; i++)
                mayor = mayor>enteros[i]? mayor: enteros[i];
      printf("\n El mayor de los numeros es: %d", mayor);
      getchar();
      getchar();

}
     
     
     
     
       
             


20-May-2012 01:22
Pablo Rampa

 El siguiente ejercicio:

 • Un programa que almacene en una tabla el número de días que tiene cada mes (su­pon­dremos que
es un año no bisiesto), pida al usuario que le indique un mes (1=enero, 12=diciembre) y muestre en
 pantalla el número de días que tiene ese mes.

#include <stdio.h>

main()
{
     int i=1;
     while (i>0 && i<=12)
     {
          int mes[12]={31,28,31,30,31,30,31,31,30,31,30,31};
          printf("\n\n\n Diga el numero que corresponde al mes que desea,\n ");
          printf("   asi: 1=enero, 2=febrero,..., 12=diciembre  =  ");
          scanf("%d", &i);
          printf("\n El mes que ha seleccionado tiene %d dias", mes[i-1]);
         
     }
}

  En este ejercicio no sé por qué tuve que inicializar la variable suma con -16; ya que en un lazo for me tomaba el valor espurio de 16. .....si me pueden aclarar, por favor.


• Un programa que almacene en una tabla el número de días que tiene cada mes (año no bisiesto),
       pida al usuario que le indique un mes (ej. 2 para febrero) y un día (ej. el día 15) y diga qué
       número de día es dentro del año (por ejemplo, el 15 de febrero sería el día número 46, el 31 de
       diciembre sería el día 365). */
       
 #include <stdio.h>
 
 main()
 {
     int i=0, d=0, m=0, suma=-16;
     int mes[12]={31,28,31,30,31,30,31,31,30,31,30,31};
     printf("\n\n Escriba un numero del 1 al 12(mes)=   ");
     scanf("%d", &m);
     for(i=0; i<m; ++i)            
         suma += mes[i-1];
     printf(" Escriba otro numero (dia)=   ");
     scanf("%d", &d);
     suma += d;
     printf(" Este es el dia numero %d del anio", suma);
     getchar();
     getchar();
 }          
             
 
 


20-May-2012 09:44
Nacho Cabanes (+83)

Cuidado: en el de "Un programa que pida al usuario 10 números enteros y calcule (y muestre) cuál es el mayor de ellos" tienes un fallo: prueba a introducir los números -5, -10, -8, -7, -11 y lo verás...


20-May-2012 11:58
Antonio Rodriguez

 En este ejercicio no sé por qué tuve que inicializar la variable suma con -16; ya que en un lazo for me tomaba el valor espurio de 16. .....si me pueden aclarar, por favor.

Creo que tienes un problema en el bucle for

     for(i=0; i<m; ++i)            
          suma += mes[i-1];

al indicar 'i=0' y despues 'mes[i-1]' el primer resultado lo va a buscar a la posición  'mes[-1]' que queda fuera de la tabla.

si cambias el bucle por este otro:

      for(i=0; i<(m-1); ++i)            
          suma += mes[i];

el programa funciona perfectamente.

Un saludo


20-May-2012 17:45
Pablo Rampa

 
 Gracias Antonio por la efectiva respuesta.

Comento que al colocar en otro lugar la declaración de la variable suma, funciona también; pero no es lo correcto.
• Un programa que almacene en una tabla el número de días que tiene cada mes (año no bisiesto),
       pida al usuario que le indique un mes (ej. 2 para febrero) y un día (ej. el día 15) y diga qué
       número de día es dentro del año (por ejemplo, el 15 de febrero sería el día número 46, el 31 de
       diciembre sería el día 365).
       
 #include <stdio.h>
 
 main()
 {
     int i=0, d=0, m=0, mes[12]={31,28,31,30,31,30,31,31,30,31,30,31};
     int suma=0;                   /*Ahora declaro suma aquí */
     printf("\n\n Escriba un numero del 1 al 12(mes)=   ");
     scanf("%d", &m);
     for(i=0; i<m; ++i)
         suma += mes[i-1];
     printf("\n Escriba otro numero (dia)=   ");
     scanf("%d", &d);
     suma += d;
     /*printf("\n Este es el dia numero %d del anio\n", suma); */
     printf(" Faltan %d dias para que finalice el anio", 365-suma);
     getchar();
     getchar();
 }          
             
  Un saludo. La aclaración de Antonio me parece excelente.


20-May-2012 19:02
Pablo Rampa

 Gracias por la aclaración estimado Nacho.

 La variable mayor está inicializada en cero.

    ¿Qué tal así?:

  . Un programa que pida al usuario 10 números enteros y  calcule (y muestre)
 cuál es el mayor de ellos.

#include <stdio.h>

main()
{
      int i, enteros[10], menor=0, mayor=0; /* Podría declarar mayor = -1000000
         o el menor número que acepte la máquina, pero no me pareció muy técnico.*/
       
      printf("\n Escriba diez numeros enteros:\n\n");
      for (i=0; i<10; i++)
        {   scanf("%d", &enteros[i]);
           /*mayor = enteros[5]-1;   Otra posible solución   (cualquier numero entre
                                                             0 y 9 entre corchetes)*/
           mayor = menor<enteros[i]? menor: enteros[i];
        }                             /* Así me aseguro que mayor tome un valor igual
                                                al menor de los datos introducidos. */                                                
           for (i=0; i<10; i++)
             
                mayor = mayor>enteros[i]? mayor: enteros[i];
           
      printf("\n El mayor de los numeros es: %d", mayor);
      getchar();
      getchar();

}
     
     
      Saludos y gracias por su atención.
     
       
             


21-May-2012 21:17
Pablo Rampa

 He aquí los tres ejercicios de la sección 5.1.3:

 
   Ejercicios propuestos:

5.1.3 i). A partir del programa propuesto en 5.1.2, que    almacenaba en una tabla
el número de días que tiene  cada mes, crear otro que pida al usuario
que le indique la fecha, detallando el día (1 al 31) y el mes (1=enero,12=diciembre), como respuesta muestre en pantalla el número de días que
quedan hasta final de año.      
       
#include <stdio.h>
 
 main()
 {
     int i=0, d=0, m=0,suma=0;
     int mes[12]={31,28,31,30,31,30,31,31,30,31,30,31};
                         
     printf("\n\n Escriba un numero del 1 al 12(mes)=   ");
     scanf("%d", &m);
     for(i=0; i<(m-1); ++i)   // m-1 en vez de m.
         suma += mes[i];      // i   en vez de  i-1.
     printf("\n Escriba otro numero (dia)=   ");
     scanf("%d", &d);
     suma += d;
     /*printf("\n Este es el dia numero %d del anio\n", suma); */
     printf(" Faltan %d dias para que finalice el anio", 365-suma);
     getchar();
     getchar();
 }          
             
 5.1.3 ii) Crear un programa que pida al usuario 10 números  y luego
    los muestre en orden inverso (del último al primero).
       
#include <stdio.h>
main()
{
     int i;
     float numeros[10];
     printf("\n Escriba  diez numeros:\n");
     for (i=0; i<10; i++)
          scanf(" %g", &numeros[i]);
          printf("\n Los numeros, en orden inverso\n");
          printf(" al que fueron introducidos, son: ");
          for (i=9; i>=0; i--)
               printf(" %g", numeros[i]);
     getchar();
     getchar();
}
   5.1.3 iii). Crear un programa que pida al usuario números,
   calcule su media y luego muestre los que están
       por encima de la media.
       
 #include <stdio.h>

main()
{
      int i;
      float numeros[10], media=-1e32, desviacion=-1e32,suma=0;  
       
      printf("\n Escriba diez numeros:\n\n");
      for (i=0; i<10; i++)
          {scanf("%g", &numeros[i]);
           suma += numeros[i];}
           media = suma/10;
           printf("\n La media es:%g", media);
           printf("\n\n Los numeros que estan por encima de la media son: ");                                                                          
           for (i=0; i<10; i++)
           {
                desviacion=(numeros[i]-media);
                if (desviacion > 0)
                     printf(" %g ", numeros[i]);
           }
      getchar();
      getchar();
}
 

 Saludos.


22-May-2012 00:22
Pablo Rampa

Aquí están otros ejercicios:

 5.2.3.i)
       Un programa que te pida tu nombre y lo muestre en pantalla separando cada letra de la siguiente
       con un espacio. Por ejemplo, si tu nombre es “Juan”, debería aparecer en pantalla “J u a n”.
       
#include <stdio.h>
#include <string.h>


 main()
{
      int i;
      char nombre[30];
     
      printf("Escriba su nombre  ");
      scanf("%s", nombre);
      //printf("Has tecleado %d letras : ", strlen(nombre));
      for (i=0; i<strlen(nombre); i++)
      printf("%c ", nombre[i]);
      getchar();
      getchar();
     
     
}
     
 5.2.3.ii)
      Un programa que te pida tu nombre y lo muestre en pantalla separando al revés.
       Por ejemplo, si tu nombre es “Juan”, debería aparecer en pantalla “nauJ”.
       
#include <stdio.h>
#include <string.h>


 main()
{
      int i;
      char nombre[30];
     
      printf(" Escriba su nombre:  ");
      scanf("%s", nombre);
      //printf("Has tecleado %d letras : ", strlen(nombre));
      printf("\n Su nombre al reves: ");
      for (i=(strlen(nombre)-1);i>=0; --i)
      printf("%c", nombre[i]);
      printf("\n Su nombre al reves y separado: ");
      for (i=(strlen(nombre)-1);i>=0; --i)
      printf("%c ", nombre[i]);
      getchar();
      getchar();
     
     
}
     
      Saludos cordiales.
   


22-May-2012 22:21
Pablo Rampa

   
          Otro ejercicio:

   5.2.4
       Un programa que te pida una frase y la muestre en pantalla sin espacios.
       Por ejemplo, si la frase es “Hola, como estás”, debería aparecer en pantalla
       “Hola,comoestás”.
       
#include <stdio.h>
//#include <ctype.h>
#include <string.h>

 main()
{
      char frase[40];
      int  i, aux;
     
      printf("Escriba una frase   ");
      for(i=0; (frase[i]=getchar())!='\n'; ++i)
           aux=i;
           for (i=0; i<=aux; ++i)
                if (frase[i]!=' ')
                putchar(frase[i]);
       
       getchar();

}

       Aparentemente estaba fácil, pero me costó mucho.
   En realidad "investigué" un poco; de otro modo, no lo
   consigo.

   Saludos.


25-May-2012 00:15
Pablo Rampa

 Otros ejercicios:
 
   /*5.2.5
       Un programa que te pida una palabra, y la almacene en la variable llamada “texto”. Luego deberá
       pedir una segunda palabra, y añadirla al final de “texto”. Finalmente, deberá pedir una tercera
       palabra, y guardarla en la variable “texto” y en otra variable llamada “texto2”. */
       
 
       
#include <stdio.h>
#include <string.h>

 main()
{
      char texto[40], aux[30], texto2[20];
     
      printf("Escriba una palabra ");
      gets(texto);  // O sea, scanf("%s", texto);
     
      printf("Escriba otra palabra ");
      gets(aux);// O sea, scanf("%s", aux);
     
      printf("Escriba otra palabra ");
      gets(texto2);  // O sea, scanf("%s", texto2);
     
      strcat(aux, texto2);
      strcat(texto, aux);
     
      printf("\n%s", texto);  // O sea, puts(texto);
      printf("\n%s", texto2);  // Osea, puts(texto2);
     
      getchar();
     
}

  /*5.2.6.i)
       Crear un programa que pida al usuario su contraseña. Deberá terminar cuando introduzca como
       contraseña la palabra "clave", pero volvérsela a pedir tantas veces como sea necesario. */
 
 #include <stdio.h>
 #include <string.h>
 
 main()
{
     int x;
     char contrasenia[10];
     char palabraClave[]="clave";
     
     do
     {
          printf("Escriba su contrasenia ");
          //scanf("%s", contrasenia);
          gets(contrasenia);
          x=strcmp(contrasenia, palabraClave);
     }
     while (x != 0);
     
     printf("Acceso concedido, ...Sea Ud. bienvenido!");
     getchar();
     
}
     
 /*5.2.6.ii)
       Crear un programa que pida al usuario su nombre y su contraseña, y no le permita seguir hasta
       que introduzca como nombre "Pedro" y como contraseña "Peter". */
       
 
 #include <stdio.h>
 #include <string.h>
 
 main()
{
     int x, y;
     char nombre[10], contrasenia[10];
     char nombreClave[]="Pedro", palabraClave[]="Peter";
     
     do
     {
          printf("Escriba su nombre ");
          gets(nombre);
         
          printf("Escriba su contrasenia ");
          gets(contrasenia);
         
          x=strcmp(nombre, nombreClave);
          y=strcmp(contrasenia, palabraClave);
     }
     while ((x!=0) || (y!=0));
     
     printf("Acceso concedido, ...Sea Ud. bienvenido!");
     getchar();
     
}
     
 /*Ejercicio propuesto:
 5.2.7  
       Un programa que pida tu nombre, tu día de nacimiento y tu mes de nacimiento y
       lo junte todo en una cadena, separando el nombre de la fecha por una coma y el día del mes por
       una barra inclinada, así: “Juan, nacido el 31/12”. */
       
 #include <stdio.h>
 #include <string.h>
 
 main()
{
     
     char nombre[30], diaNacimiento[30], mesNacimiento[30];
     char auxComaEspacio[30]=", nacido el ", auxDiagonal[30]="/";      
     
     printf("Escriba su nombre:  ");
     gets(nombre);
         
     printf("Escriba el numero del dia en que nacio:  ");
     gets(diaNacimiento);
         
     printf("Escriba el numero del mes en que nacio:  ");
     gets(mesNacimiento);
         
     strcat(auxDiagonal, mesNacimiento);
     strcat(diaNacimiento, auxDiagonal);
     strcat(nombre, auxComaEspacio);
     strcat(nombre, diaNacimiento);
     
     printf("\n  %s", nombre);
     
     getchar();
     
}
     
 /*5.3.i)
       Un programa guarde los nombres de los meses. El usuario deberá indicar un número de mes (por
       ejemplo, 3) y se le mostrará el nombre de dicho mes (por ejemplo, Marzo). */
       
 #include <stdio.h>
 #include <string.h>
 
 main()
 {
       int i;
       char nombreMes[12][12]={"Enero", "Febrero", "Marzo",
                                  "Abril", "Mayo", "Junio",
                           "Julio", "Agosto", "Septiembre",
                      "Octubre", "Noviembre", "Diciembre"};
       
       printf("\n Escriba un numero, del 1 al 12 : ");
       scanf("%d", &i);
       
       printf("\n El numero %d corresponde al mes de %s", i, (nombreMes-1)[i]);
       
       getchar();
       getchar();
       
 }

 /*5.3.ii)
       Usar un array de 3 dimensiones para guardar los nombres de los meses en español e inglés. El
       usuario deberá indicar un número de mes (por ejemplo, 3) y se le mostrará el nombre de dicho
       mes en español (Marzo) y en inglés (March). */
       
 #include <stdio.h>
 #include <string.h>
 
 main()
 {
       int i;
       char mesEspaniolIngles[2][12][12]={"Enero", "Febrero", "Marzo",
                                             "Abril", "Mayo", "Junio",
                                      "Julio", "Agosto", "Septiembre",
                                  "Octubre", "Noviembre", "Diciembre",
                                       "January", "February", "March",
                                               "April", "May", "June",
                                        "July", "August", "September",
                                    "October", "November", "December"};
       
       printf("\n Escriba un numero, del 1 al 12 : ");
       scanf("%d", &i);
       i--;
       
       printf("\n El numero digitado corresponde al mes de:  %s / %s",
                   mesEspaniolIngles[0][i], mesEspaniolIngles[1][i]);      
       getchar();
       getchar();
       
 }




    .....Saludos.


27-May-2012 11:12
Nacho Cabanes (+83)

Para calcular un máximo o un mínimo, hay básicamente dos alternativas:

* Tomar un valor claramente fuera de rango: un máximo en sea -10000 y un mínimo que sea +10000. Aun así, esto sigue siendo peligroso si no tienes certeza de que los valores están en un rango muy limitado; si pueden tener cualquier valor, quizá dé la casualidad de que todos estén por debajo de ese "máximo provisional" y obtengas resultados incorrectos.

* Tomar el primer número como valor provisional para el máximo y para el mínimo, y comenzar las comparaciones a partir del segundo (preferible).


27-May-2012 11:28
Nacho Cabanes (+83)

El 5.2.4 lo haces un poco rebuscado. No necesitas un doble "for", se puede hacer muy parecido al de 5.2.3:

#include <stdio.h>
#include <string.h>

int  main()
{
     char frase[80];
     int  i;
     
     printf("Escriba una frase  ");
     gets(frase);

     for(i=0; i < strlen(frase); i++)
           if (frase[i] != ' ')
               printf("%c",frase[i]);
       
     return 0;

}


27-May-2012 12:22
Nacho Cabanes (+83)

Por cierto, una cosa más, que quizá ya te hayas dado cuenta...

En el 5.3.1 accedes a los datos de cada mes haciendo

(nombreMes-1)[i]

que, aunque algunos compiladores te lo permitan, no tiene mucho sentido: si el array se llama "nombreMes", y empieza a contar desde 0, deberías escribir:

nombreMes[i-1]

de modo que el fuente completo (coge la costumbre de hacer "int main" en vez de simplemente "main", y de terminar con "return 0" si no hay errores) podría quedar así:

#include <stdio.h>
 
int main()
{
       int i;
       char nombreMes[12][80]={"Enero", "Febrero", "Marzo",
           "Abril", "Mayo", "Junio",
           "Julio", "Agosto", "Septiembre",
           "Octubre", "Noviembre", "Diciembre"};
       
       printf("Escriba un numero, del 1 al 12 : ");
       scanf("%d", &i);
       
       printf("El numero %d corresponde al mes de %s", i, nombreMes[i-1]);
       
       return 0;
}


28-May-2012 23:59
Pablo Rampa


 Gracias, estimado Nacho por esas muy oportunas respuestas.
 Pero, quiero comentar que ahora si me siento en "shock".
 Recién me estoy dando cuenta del lío en que me he enfrascado al  querer aprender a programar.
 Pienso seriamente en volver a los ejercicios de los primeros capítulos; a ver si así vuelvo a tomar rumbo, pues veo que los capítulos que siguen van a estar más difíciles.
 
 El ejercicio 5.4 me tiende a desanimar. Cuando quiero buscar una
cadena en otra usando "strstr" me dice que no se puede convertir
"char*" a "const char".  No puedo pasar de ahí.
  Agradecería una pista, por favor.
 
  Lo he comenzado así:
 
    /*5.4.i)
       Un programa que pida 10 nombres y los memorice. Después deberá pedir que se teclee un nombre
       y dirá si se encuentra o no entre los 10 que se han tecleado antes. Volverá a pedir otro
       nombre y a decir si se encuentra entre ellos, y así sucesivamente hasta que se teclee “fin”. */

 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
 
 int main()
 {
       int i, j, z;
       char x, nombres[10][10], otrosNombres[10][10], fin[]="fin";
       
       printf("\n Escriba 10 nombres: \n");
       for (i=0; i<10; i++)
           scanf("%s", &nombres[i]);
       for (i=0; i<10; i++)    
           printf("%s  ", nombres[i]);
           printf("%s", fin);
      do
       {
                         
                printf("\n Escriba otro nombre, o \"fin\" para terminar: ");
                scanf("%s", otrosNombres);
               
               
                if (strstr(nombres, otrosNombres)!= NULL);
               
                     printf(" Este nombre se encuentra en la lista\n");
                     
                     printf(" Este nombre no se encuentra en la lista\n");
                 
        }
        while (strcmp(otrosNombres, fin) != 0);  
           
       getchar();
       getchar();
 }
}
                 

 


29-May-2012 23:17
bruno zelaia montero

Hola Pablo!

Yo llevo un tiempo desconectadillo del curso, aunque lo voy a volver a retomar esta semana...pero vamos al grano, a lo que te interesa...
Para empezar te haré unas recomendaciones personales...
Tómalo con calma, ves poco a poco, sin prisas pero sin pausas, haz ejercicios muchos ejercicios...y aunque a veces desespera, no te desanimes y al revés, tómate los errores como lo que son: la mejor oportunidad de aprender.
Cuando algo va mal suele ser porque no se tiene claro como funciona algo o porque no se conoce al cien x cien...entonces expon la duda y entre todos sacaremos la solución aunque hay que reconocer que Nacho contesta muy rápido y lo explica muy bien.
El fallo que te da a mi también me lo dio en algún ejercicio y es un fallo muy común.
Para empezar creo que te sobran variables por un tubo por lo que he visto así a grosso modo o no entiendo para que las quieres...
el otro fallo creo que está aquí:

while (strcmp(otrosNombres, fin) != 0);  

Semantic Issue: Incompatible pointer types passing 'char [10][10]' to parameter of type 'const char *'
este es el fallo que me da en el compilador, repasa bien como funciona el strcmp

A continuación te adjunto como hice yo el ejercicio para ver si te sirve de ayuda.
#include <stdio.h>
#include <string.h>
main ()
{
    char nombres[10][20];
    char nom_usu[20]="";
    char final[6]="final";
    int i=0;
    int v=0;
   
    printf("introduce 10 nombres por favor\n");
      for (i=0;i<10;i++)
      {
      gets (nombres[i]);
      }
      while (strcmp(nom_usu,final)!=0)
    {
          printf("introduzca un nombre, revisaremos si ya esta, para salir teclee final\n");
          gets(nom_usu);
          for (i=0;i<10;i++)
                       {
                       v=(strcmp(nom_usu,nombres[i]));
                       if (v==0) break;
                       }
          if (v==0) printf ("el nombre estaba en la lista\n");
          else printf ("el nombre no estaba en la lista\n");
    }
   
    }

PD: a Nacho no le gusta mucho que se use el break pero bueno... ;P
PD2: Animo y no te desanimes! :)


30-May-2012 05:38
Pablo Rampa

 Muchas gracias, Bruno; por esa oportuna, efectiva y  reanimante
 respuesta. Es bueno que personas como tú releven, de vez en
 cuando, al Profesor Nacho; que me imagino que pasa muy atareado.
 De paso, se le agradece por el curso tan bien estructurado y que
 de toma el tiempo para atender a tantos estudiantes y aficionados
 a la programación.

 Por mi parte, te agradezco el aporte de conocimiento y de
 motivación.  Y, si más sdelante, puedo colaborar con algotras
 personas que comienzan este camino, lo haré con mucho gusto.
 Ya que esto me gusta. Lo de desistir era broma.
 
 Te comento que estoy interesado en la programación de circuitos
 integrados en Assembler, ya que me dedico a la reparación.
 Escogí el ensamblador, sobretodo porque todo se consigue gratis.
 Pero estoy viendo que en C también se puede llegar a programar a
 nivel de bits.

 He dejado de practicar el Assembler por un rato, para no
 confundirme. Pero, cuando entienda más el C, volveré al
 Ensamblador. A menos que encuentre mejores prestaciones en C.
 
 Bien, ya no C si C o no C, pero lo que sí C es que aquí C
 aprende mucho.

         ...Un saludo cordial
         

 


31-May-2012 01:45
Pablo Rampa


 Gracias a la ayuda de Bruno, lo he realizado así:

 5.4.i)
       Un programa que pida 10 nombres y los memorice. Después deberá pedir que se teclee un nombre
       y dirá si se encuentra o no entre los 10 que se han tecleado antes. Volverá a pedir otro
       nombre y a decir si se encuentra entre ellos, y así sucesivamente hasta que se teclee “fin”.

 #include <stdio.h>
 #include <string.h>
 
 main()
 {
       int i, j;
       char nombres[10][10], otrosNombres[10], fin[]="fin";
       
       printf("\n Escriba 10 nombres: \n");
       for (i=0; i<10; i++)
           scanf("%s", &nombres[i]);
       for (i=0; i<10; i++)    
           printf("%s  ", nombres[i]);
       do
       {  
                printf("\n Escriba otro nombre, o \"fin\" para terminar: ");
                scanf("%s", otrosNombres);
               
                for (i=0,j=0; i<10; i++,j++)
                {
                     if (strcmp(otrosNombres, nombres[i]) == 0)
                          j--;  
                }
                if (i != j)
                      printf(" Este nombre se encuentra en la lista\n");
                else    
                      printf(" Este nombre no se encuentra en la lista\n");
                         
        }
        while (strcmp(otrosNombres, fin) != 0);  
           
       getchar();
 }

    Entre otros, el error garrafal era declarar la cadena
 "otrosNombres[10]" como "otrosNombres[10][10]".
 
 Aparte, ¿no sé si hay manera de recoger el texto para que aparezca como se ha digitado de manera que no se desparrame?
         
        ..... Saludos.


06-Jun-2012 03:29
Pablo Rampa

 
 
 He aquí otro ejercicio que me ofreció la dificultad de salir
 al presionar "enter", sin haber tecleado ningún nombre.

 
    5.4.ii)
    Un programa que prepare espacio para un máximo de 100
    nombres (de un máximo de 80 letras cada uno). El usuario
    deberá ir introduciendo un nombre cada vez, hasta que se
    pulse Intro sin teclear nada, momento en el que dejarán
    de pedirse más nombres y se mostrará en pantalla la lista
    de los nombres que se han introducido.  
 
 #include <stdio.h>
 #include <string.h>

 int main()
 {
     
     char nombres[100][80];  // Reserva espacio de memoria.
     int i=0;                // Contador de nombres.
     int j=0;                // Contador de nombres efectivos.
   
     printf("Escribe varios nombres (maximo 100): \n");
     printf("(Para salir presione otra vez \"ENTER\")\n");

     for (i=0; i<100; i++)
     {
          gets(nombres[i]);
          j++;
          if (strcmp(nombres[i], "")==0)   // Detecta cadena
          break;                           // vacía.
                     
     }
     for(i=0;i<j;i++)
           printf("%s ", nombres[i]);
     
     getchar();
     return 0;
     
 }      
 
    .....Un saludo cordial.


09-Jun-2012 04:11
Pablo Rampa

 El primer ejercicio de STRUCT:

  5.5.1.i)
       Un “struct” que almacene datos de una canción en formato
 MP3: Artista, Título, Duración (en segundos), Tamaño del    
 fichero(en KB).
   Un programa debe pedir los datos de una canción al usuario,
   almacenarlos en dicho “struct” y después mostrarlos en
 panyalla.
   
  #include <stdio.h>
  int main()
  {
      int i, n;
 
      struct  discoMP3
      {
           char nombreArtista[30];
           char tituloCancion[30];
           int duracionenSegundos;
           float tamanioFicheroKB;
      }cancion;
     
      printf("\n \"STRUCT\" para guardar datos de una
      cancion\n");
      printf("           de un disco en formato MP3");
     
      printf("\n\n Nombre del artista: ");
      gets(cancion.nombreArtista);
           
      printf(" Titulo de la cancion: ");
      gets(cancion.tituloCancion);
           
      printf(" Duracion en segundos: ");
      scanf("%d", &cancion.duracionenSegundos);
           
      printf(" Espacio de memoria en KB: ");
      scanf("\n\n%g", &cancion.tamanioFicheroKB);
           
      printf("\n\n\n\tSALIDA:");
         
      printf("\n Artista: %s", cancion.nombreArtista);
      printf("\n Cancion: %s", cancion.tituloCancion);
      printf("\n Duracion: %d segundos",
      cancion.duracionenSegundos);
      printf("\n Memoria: %g KB\n", cancion.tamanioFicheroKB);
      getchar();
      getchar();
     
      return 0;
  }
     
      .....Saludos!
     


10-Jun-2012 07:10
Nacho Cabanes (+83)

El 5.4.1 lo haces de forma un tanto rebuscada, sobre todo la comprobación de si el dato ya existía o no. Yo eliminaría el for controlado por dos variables, que no es algo simple, y me limitaría a usar una variable de control (un "flag" o "bandera"), que memorice si se ha encontrado el texto que se buscaba o no:


 // 5.4.1
 
 #include <stdio.h>
 #include <string.h>
 
 int main()
 {
       int i;
       char nombres[10][80];
       char nombreBuscar[80];
       int encontrado;
     
       printf("\n Escriba 10 nombres: \n");
     
       for (i=0; i<10; i++)
           scanf("%s", &nombres[i]);
       
       printf("\n Ha introducido: ");
       for (i=0; i<10; i++)    
           printf("%s  ", nombres[i]);
       
       do
       {  
               printf("\n Escriba otro nombre, o \"fin\" para terminar: ");
               scanf("%s", &nombreBuscar);
               encontrado = 0;
           
               if (strcmp(nombreBuscar, "fin") != 0)
               {
               
                   for (i=0; i<10; i++)
                   {
                         if (strcmp(nombreBuscar, nombres[i]) == 0)
                             encontrado = 1;  
                   }
                   if (encontrado == 1)
                         printf(" Este nombre se encuentra en la lista\n");
                   else    
                         printf(" Este nombre no se encuentra en la lista\n");
               }
                         
       }
       while (strcmp(nombreBuscar, "fin") != 0);  
           
       getchar();
       return 0;
 }


11-Jun-2012 04:26
Pablo Rampa


Gracias, estimado Nacho, por la corrección al ejercicio 5.4.i. Aquí va otro ejercicio:

5.5.2.i)
    Ampliar el programa del apartado 5.5.1, para que almacene  
datos de hasta 100 canciones. Deberá tener un menú que permita las opciones: añadir una nueva canción, mostrar el título de todas las canciones, buscar la canción que contenga un cierto texto (en el artista o en el título).
       
#include <stdio.h>
#include <string.h>

struct  discoMP3
 {
       char nombreArtista[40];
       char tituloCancion[40];
       int duracionenSegundos;
       float tamanioFicheroKB;
 }cancion[100], auxiliarT[100];
   
       
int main()
{
   char c, texto[20];
   int  i=0, j=0, n=0;
     
   printf("\"STRUCT\" para guardar hasta 100 canciones\n");
   printf("    de un disco en formato MP3");
   printf("\n\n\n\tLista de OPCIONES:");
   printf("\n\n Pulse A para agregar una nueva cancion.");
   printf("\n Pulse T para mostrar el titulo de todas las canciones.");
   printf("\n Pulse B para buscar la cancion que tenga un cierto ");
   printf("\n            texto en el artista o en el titulo.");
   printf("\n Pulse S para salir del programa.");
   lazo: printf("\n\n\t Por favor, \n");
   printf("\t introduzca la OPCION que desee: ");
   c = getchar();                    
   switch (c)
   {
    case 'A':
      lazo1: printf("\n\n Cuantas canciones va a guardar? : ");
         scanf("%d", &n);
         if (n > 0 && n <= 100)
         {
           for (i=0; i<n; i++)
           {
           printf("\n\n\tTrack No. %d\n", i+1);
                     
           printf(" Nombre del artista: ");
           scanf(" %[^\n]", cancion[i].nombreArtista);
                     
           printf(" Titulo de la cancion: ");
           scanf(" %[^\n]", cancion[i].tituloCancion);
                         
sprintf(auxiliarT[i].tituloCancion,"%s",cancion[i].tituloCancion);
           printf(" Duracion en segundos: ");
           scanf("%d", &cancion[i].duracionenSegundos);
           printf(" Espacio de memoria en KB: ");
           scanf("%g", &cancion[i].tamanioFicheroKB);
           getchar();
           }
           printf("\n\n\n\tSALIDA:");
           for (i=0; i<n; i++)
           {
              printf("\n\n\tTrack No. %d\n", i+1);
              printf("Artista: %s", cancion[i].nombreArtista);
              printf("\nTitulo: %s", cancion[i].tituloCancion);
              printf("\nDuracion: %d segundos",
                             cancion[i].duracionenSegundos);
              printf("\nMemoria: %g KB\n",
                             cancion[i].tamanioFicheroKB);
           }
           goto lazo;
               
         }
         else
           printf("Escriba un numero entre 1 y 100.");
           goto lazo1;
     case 'T':
           puts("\nLista de canciones:\n");
           for (i=0; i<n; i++)
              printf("%d.%s\n", (i+1), auxiliarT[i].tituloCancion);
              if (n == 0)
                 printf(" No se encontro ninguna cancion.");
                 getchar();    
                 goto lazo;
     case 'B':
        printf("\n Escriba una palabra o un pequenio texto\n ");
        printf(" que se encuentre en el nombre del artista\n ");
        printf(" o en el titulo de la cancion: ");
             
        scanf(" %[^\n]", texto);
             
        for (i=0,j=0; i<n; i++,j++)
        {
          if (strstr(cancion[i].nombreArtista, texto) ||
                strstr(cancion[i].tituloCancion, texto)!=NULL)
          {
          printf("\n Se encontro coincidencia en el Track %d\n",
                          i+1);
             j--;
          }  
        }
        if (i == j)
             printf("\n No se encontro ninguna coincidencia.");
             
             getchar();
             goto lazo;
             
      case 'S':
             break;
                       
      default:
            puts("\n...ERROR!");
            goto lazo;
    }
    getchar();
    return 0;
}
                       
                       
       Si parece rebuscado, es que me costó
mucho realizarlo.

       Saludos!                
 
     
     


14-Jun-2012 01:01
Pablo Rampa


Aquí está otro ejercicio:

/*+5.5.2.ii)
Un programa que permita guardar datos de "imágenes"(ficheros de  ordenador que contengan fotografías o cualquier otro tipo de información gráfica). De cada imagen se debe guardar: nombre (texto), ancho en píxeles (por ejemplo 2000), alto en píxeles (por ejemplo, 3000), tamaño en Kb (por ejemplo 145,6). El programa debe ser capaz de almacenar hasta 700 imágenes(deberá avisar cuando su capacidad esté llena). Debe permitir las opciones: añadir una ficha nueva, ver todas las fichas (número
y nombre de cada imagen), buscar la ficha que tenga un
cierto nombre. */

       
#include <stdio.h>
#include <string.h>

struct  graficos
 {
       char nombre[40];
       int ancho;
       int alto;
       float tamanioKB;
 }imagen[700], auxNombre[700];
 
 int main()
{
   char c, texto[40];
   int  i=0, j=0, n=0;
     
   printf("\"STRUCT\" para guardar hasta 700 imagenes\n");
   printf("\n\n\n\tLista de OPCIONES:");
   printf("\n\n Pulse A para agregar una ficha nueva.");
 printf("\n Pulse V para ver el nombre de todas las fichas\n ");
   printf("              (No. y nombre de cada imagen).");
   printf("\n Pulse B para buscar la ficha por su nombre ");
   printf("\n Pulse S para salir del programa.");
   lazo: printf("\n\n\t Por favor, \n");
   printf("\t introduzca la OPCION que desee: ");
   c = getchar();                    
   switch (c)
   {
     case 'A':
       lazo1: printf("\n\n Cuantas imagenes va a guardar? :  ");
       scanf("%d", &n);
       if (n > 0 && n <= 700)
       {
          for (i=0; i<n; i++)
          {
          printf("\n\n\tImagen No. %d\n", i+1);
                     
          printf(" Nombre de la imagen: ");
          scanf(" %[^\n]", imagen[i].nombre);
          printf(" Anchura de la imagen en Pixeles: ");
          scanf(" %dPixeles", &imagen[i].ancho);
          printf(" Altura de la imagen en Pixeles: ");
          scanf("%dPixeles", &imagen[i].alto);
          printf(" Espacio de memoria en KB: ");
          scanf("%gKB", &imagen[i].tamanioKB);
          getchar();
          }
          if (i == 699)
              printf("\n\n\n\tCapacidad COMPLETADA!");
                   
              goto lazo;
          }
          else
              printf("Escriba un numero entre 1 y 700.");
              goto lazo1;
   case 'V':
         puts("\nLista de imagenes:\n");
         for (i=0; i<n; i++)
             printf("%d.%s\n", (i+1), imagen[i].nombre);
             if (n == 0)
                  printf(" No se encontro ninguna imagen.");
                  getchar();    
                  goto lazo;
   case 'B':
      printf("\n Escriba el nombre de la imagen que busca:\n ");
       scanf(" %[^\n]", texto);
       j=0;
       for (i=0; i<n; i++)
       {
           if (strcmp(imagen[i].nombre, texto) == NULL)
           {
   printf("\n Se encontro coincidencia en el Numero %d\n", i+1);
             j++;
           }
       }
       if (j == 0)
           printf("\n No se encontro ninguna coincidencia.");
             
           getchar();
           goto lazo;
             
   case 'S':
        break;
                       
   default:
        puts("\n...ERROR!");
        goto lazo;
   }
   getchar();
   return 0;
}
                       
     .....Saludos cordiales!


14-Jun-2012 03:10
Pablo Rampa


Siguiente ejercicio:

 5.5.3
 Ampliar el programa del primer apartado de 5.5.2, para que el
campo “duración” se almacene como minutos y segundos, usando un
“struct” anidado que contenga a su vez estos dos campos.

       
#include <stdio.h>
#include <string.h>
struct tiempo
{
       int minutos;
       int segundos;
};

struct  discoMP3
 {
       char nombreArtista[40];
       char tituloCancion[40];
       struct tiempo duracion;
       float tamanioFicheroKB;
 }cancion[100], auxiliarT[100];
 
       
int main()
{
   char c, texto[20];
   int  i=0, j=0, n=0;
     
   printf("\"STRUCT\" para guardar hasta 100 canciones\n");
   printf("    de un disco en formato MP3");
   printf("\n\n\n\tLista de OPCIONES:");
   printf("\n\n Pulse A para agregar una nueva cancion.");
   printf("\n Pulse T para mostrar el titulo de todas las canciones.");
printf("\n Pulse B para buscar la cancion que tenga un cierto ");
   printf("\n            texto en el artista o en el titulo.");
   printf("\n Pulse S para salir del programa.");
   lazo: printf("\n\n\t Por favor, \n");
   printf("\t introduzca la OPCION que desee: ");
   c = getchar();                    
   switch (c)
   {
    case 'A':
      lazo1: printf("\n\n Cuantas canciones va a guardar? :  ");
      scanf("%d", &n);
      if (n > 0 && n <= 100)
      {
         for (i=0; i<n; i++)
         {
            printf("\n\n\tTrack No. %d\n", i+1);
                     
            printf(" Nombre del artista: ");
            scanf(" %[^\n]", cancion[i].nombreArtista);
                     
            printf(" Titulo de la cancion: ");
            scanf(" %[^\n]", cancion[i].tituloCancion);
                         
            sprintf(auxiliarT[i].tituloCancion, "%s",  cancion[i].tituloCancion);
                     
            printf(" Duracion en minutos: ");
            scanf("%d", &cancion[i].duracion.minutos);
            printf(" ...y segundos: ");
            scanf("%d", &cancion[i].duracion.segundos);
            printf(" Espacio de memoria en KB: ");
            scanf("%g", &cancion[i].tamanioFicheroKB);
            getchar();
         }
         printf("\n\n\n\tSALIDA:");
         for (i=0; i<n; i++)
         {
             printf("\n\n\tTrack No. %d\n", i+1);
             printf("Artista: %s", cancion[i].nombreArtista);
             printf("\nTitulo: %s", cancion[i].tituloCancion);
             printf("\nDuracion: %d min, %d seg",
   cancion[i].duracion.minutos, cancion[i].duracion.segundos);
             printf("\nMemoria: %g KB\n",
                                 cancion[i].tamanioFicheroKB);
        }
        goto lazo;
               
      }
      else
          printf("Escriba un numero entre 1 y 100.");
          goto lazo1;
case 'T':
     puts("\nLista de canciones:\n");
     for (i=0; i<n; i++)
         printf("%d.%s\n", (i+1), auxiliarT[i].tituloCancion);
         if (n == 0)
             printf(" No se encontro ninguna cancion.");
             getchar();    
             goto lazo;
case 'B':
    printf("\n Escriba una palabra o un pequenio texto\n ");
    printf(" que se encuentre en el nombre del artista\n ");
    printf(" o en el titulo de la cancion: ");
             
    scanf(" %[^\n]", texto);
             
    for (i=0,j=0; i<n; i++,j++)
        {
        if (strstr(cancion[i].nombreArtista, texto) ||
             strstr(cancion[i].tituloCancion, texto)!=NULL)
        {
        printf("\n Se encontro coincidencia en el Track %d\n",
        i+1);
        j--;
        }  
        }
        if (i == j)
        printf("\n No se encontro ninguna coincidencia.");
             
        getchar();
        goto lazo;
             
 case 'S':
        break;
                       
 default:
        puts("\n...ERROR!");
        goto lazo;
   }
   getchar();
   return 0;
}
                       
                       
   PD: Se me escapó de nuevo un for con el
operador coma.
    .....Saludos!                      
 
     
     


14-Jun-2012 13:45
Pablo Rampa

Otro ejercicio:
5.6.i)
Un programa que pida el nombre, el apellido y la edad de una persona, los almacene en un “struct” y luego muestre los tres datos en una misma línea, separados por comas.
 
#include <stdio.h>
#include <string.h>

struct datos
{
     char nombre[20];
     char apellido[20];
     int edad;
}persona;
int main()
{
  int i;
     
  printf("Escriba los datos que se le piden, de una persona:");
  printf("\n\nNombre: ");
scanf(" %[^\n]",persona.nombre);//previendo que puede ser más de
                               // un nombre.
  printf("\nApellido: ")
  scanf(" %[^\n]", persona.apellido); //puede ser más de un  
                                      //apellido.
  printf("\nEdad: ");
  scanf(" %d", &persona.edad);
 
  printf("\n\n\tSALIDA:");
 
  printf("\n\nDatos: %s, %s, %d anios",
      persona.nombre, persona.apellido, persona.edad);
 
  getchar();
  getchar();
 
  return 0;
}


.....Saludos a todos.
     


17-Jun-2012 11:14
Nacho Cabanes (+83)

Cuidado con formatos avanzados como

scanf(" %[^\n]",persona.nombre);

hasta donde yo sé, no es un formato estándar, que acepten todos los  compiladores. Si quieres que funcione siempre, usa "gets" en vez de esa expresión:

gets(persona.nombre);


19-Jun-2012 05:50
Pablo Rampa

Gracias por la corrección, estimado Nacho.

Aquí está de nuevo:

5.6.i)
    Un programa que pida el nombre, el apellido y la edad de una persona, los almacene en un “struct” y luego muestre los tres datos en una misma línea, separados por comas.
 
#include <stdio.h>
#include <string.h>

struct datos
{
     char nombre[20];
     char apellido[20];
     int edad;
}persona;
int main()
{
  int i;
     
  puts("Escriba los datos que se le piden, de una persona:");
  puts("Nombre: ");
  gets(persona.nombre);  
  puts("Apellido: ");                    
  gets(persona.apellido);
  puts("Edad: ");
  scanf("%d", &persona.edad);
 
  printf("\n\n\tSALIDA:");
 
  printf("\n\nDatos: %s, %s, %d anios",
      persona.nombre, persona.apellido, persona.edad);
 
  getchar();
  getchar();
 
  return 0;
}

Y aquí está el siguiente:

5.6.ii)
   Un programa que pida datos de 8 personas: nombre, dia de nacimiento, mes de nacimiento, y año de nacimiento (que se deben almacenar en una tabla de structs). Después deberá repetir lo siguiente: preguntar un número de mes y mostrar en pantalla los datos de las personas que cumplan los años durante ese mes. Terminará de repetirse cuando se teclee 0 como número de mes.

#include <stdio.h>
#include <string.h>

struct  datos
 {
       char nombre[40];
       int diaNacimiento;
       int mesNacimiento;
       int anioNacimiento;
 }persona[8];
 
 int main()
{
   int  i, j, nMes;
   char nombreMes[12][12]={"Enero", "Febrero", "Marzo",  "Abril", "Mayo", "Junio", "Julio", "Agosto", "Septiembre",
                   "Octubre", "Noviembre", "Diciembre"};
       
   printf("\"STRUCT\" para guardar datos de 8 personas:\n");
   for (i=0; i<8; i++)
   {
        printf("\n Nombre: ");
        scanf(" %s", persona[i].nombre);
        printf("\n Dia de nacimiento: ");
        scanf(" %d", &persona[i].diaNacimiento);
        printf("\n Mes de nacimiento: ");
        scanf(" %d", &persona[i].mesNacimiento);
        printf("\n Anio de nacimiento: ");
        scanf(" %d", &persona[i].anioNacimiento);
   }
   
   do
   {
      do
      {
         printf("\n\n\n\t Digite un numero de mes: ");
         printf("\n (1=enero, 2=febrero,...,12=diciembre).");
         printf("\n\tEscriba 0 para salir.     ");
         scanf(" %d", &nMes);
         if (nMes<0 || nMes>12)
            printf("\tERROR - No. fuera de rango");
      }
      while (nMes<0 || nMes>12);
     
      printf("\n Cumpleanieros de %s: \n", nombreMes[nMes-1]);
       
      j = 0;
      for (i=0; i<12; i++)
      {
          if (persona[i].mesNacimiento == nMes)
          {
              printf ("\n%s: ", persona[i].nombre);
              printf("%d/", persona[i].diaNacimiento);
              printf("%d/", persona[i].mesNacimiento);
              printf("%d.", persona[i].anioNacimiento);
              j++;
          }
       
       }
       if (j == 0)
          printf(" Nadie cumpleanios este mes.");
   }
   while (nMes != 0);
   getchar();
   
   return 0;
}
           
        Espero no haber roto ningun plato esta vez.

  Pero, no me explico, ¿porqué se va estrechando el espacio
  cada vez más!  
   
   .....Saludos cordiales.  
   
   
 



     


20-Jun-2012 06:57
Nacho Cabanes (+83)

Decías:

Pero, no me explico, ¿porqué se va estrechando el espacio cada vez más!  

Sencillo: por defecto, el foro muestra las respuestas un poco más a la derecha que la pregunta de la que dependen, así que si usas mucho el "responder", parece que se va estrechando el espacio disponible.

Si en el desplegable superior cambias a la opción "Ordenar desde el más antiguo", se verá un poco mejor.

Por cierto, una curiosidad: en tu último fuente (5.6.ii), prueba a pedir primero la fecha de nacimiento y luego el nombre, quizá pasen "cosas raras". Pruébalo y cuenta si te funciona bien...


22-Jun-2012 00:59
Pablo Rampa

 Gracias, estimado Nacho por tomarse su tiempo para responder
nuestras inquietudes.
 Gracias por el tip. Ahora ya caben más de 60 caracteres por línea.
 Respecto al ejercicio 5.6.ii le comento lo siguiente:
Al correrlo como me dijo, se trastornan las fechas.
Para corregirlo, modifiqué el orden de los miembros del Struct,
asi:

5.6.ii)
   Un programa que pida datos de 8 personas: nombre, dia de nacimiento,
  mes de nacimiento, y año de nacimiento (que se deben almacenar en una
  tabla de structs). Después deberá repetir lo siguiente: preguntar un
  número de mes y mostrar en pantalla los datos de las personas que
  cumplan los años durante ese mes. Terminará de repetirse cuando se
  teclee 0 como número de mes.  

#include <stdio.h>
#include <string.h>

struct  datos
 {
       int diaNacimiento;
       int mesNacimiento;
       int anioNacimiento;
       char nombre[40];
 }persona[8];
 
 int main()
{
   int  i, j, nMes;
   char nombreMes[12][12]={"Enero", "Febrero", "Marzo",    "Abril", "Mayo", "Junio", "Julio", "Agosto",
"Septiembre", "Octubre", "Noviembre", "Diciembre"};
       
   printf("\"STRUCT\" para guardar datos de 8 personas:\n");
   for (i=0; i<8; i++)
   {
        printf("\n Dia de nacimiento: ");
        scanf(" %d", &persona[i].diaNacimiento);
        printf("\n Mes de nacimiento: ");
        scanf(" %d", &persona[i].mesNacimiento);
        printf("\n Anio de nacimiento: ");
        scanf(" %d", &persona[i].anioNacimiento);
        printf("\n Nombre: ");
        scanf(" %s", persona[i].nombre);
   }
   
   do
   {
      do
      {
         printf("\n\n\n\t Digite un numero de mes: ");
         printf("\n (1=enero, 2=febrero,...,12=diciembre).");
         printf("\n\tEscriba 0 para salir.     ");
         scanf(" %d", &nMes);
         if (nMes<0 || nMes>12)
            printf("\tERROR - No. fuera de rango");
      }
      while (nMes<0 || nMes>12);
     
      printf("\n Cumpleanieros de %s: \n", nombreMes[nMes-1]);
       
      j = 0;
      for (i=0; i<12; i++)
      {
          if (persona[i].mesNacimiento == nMes)
          {
              printf ("\n%s: ", persona[i].nombre);
              printf("%d/", persona[i].diaNacimiento);
              printf("%d/", persona[i].mesNacimiento);
              printf("%d.", persona[i].anioNacimiento);
              j++;
          }
       
       }
       if (j == 0)
          printf(" Nadie cumpleanios este mes.");
   }
   while (nMes != 0);
   getchar();
   
   return 0;
}

Le comento que en el siguiente ejercicio tengo problema para salir sin teclear nombre. Ya lo había resuelto antes, pero no
trabajaba con structs.
           
 .....Saludos, Nacho. Se agradece la atención.          
   
   
   
   
 


23-Jun-2012 01:16
Pablo Rampa

  Estimado Nacho:
En este ejercicio me causa  problemas un getchar(). Si no lo pongo, me coloca de una vez dos items: nombre y dirección. Si lo coloco, me elimina la letra inicial del nombre que se introduce.
Gracias por la ayuda.

5.6.iii)
Un programa que sea capaz de almacenar los datos de 50 personas:
nombre, dirección, teléfono, edad (usando una tabla de structs).
Deberá ir pidiendo los datos uno por uno, hasta que un nombre se introduzca vacío (se pulse Intro sin teclear nada). Entonces deberá aparecer un menú que permita: Mostrar la lista de todos los nombres.Mostrar las personas de una cierta edad. Mostrar las personas cuya inicial sea la que el usuario indique. Salir del programa (lógicamente, este menú debe repetirse hasta que se escoja la opción de “salir”).  

#include <stdio.h>
#include <string.h>

struct  datos
 {
       char nombre[40];
       char direccion[40];
       int telefono;
       int edad;
 }personas[50];
 
 int main()
{
   int i, j=0, k=0, anios, opcion;
   char inicial, menu[]="menu";
       
printf("\n------\"STRUCT\" para guardar datos de 50 personas.\n"
 "-(Para salir, en vez de escribir un nombre, pulse ENTER).\n"
        "----------Escriba los datos que se le piden: \n");
         
   
   for (i=0; i<50; i++)
   {
      printf("\n Nombre: ");
      getchar();   /* ¿Como poder evitar que este getchar()
                      se coma la letra inicial del nombre? */
      gets(personas[i].nombre);
         
      j++;
      if (strcmp(personas[i].nombre, "")==0)
      break;
      printf(" Direccion: ");
      scanf("%s", personas[i].direccion);
      printf(" Telefono: ");
      scanf("%d", &personas[i].telefono);
      printf(" Edad: ");
      scanf("%d", &personas[i].edad);
  }
  lazo: printf("\n\"MENU:\"\n"
  "1.-Mostrar la lista de personas,\n"
  "2.-Mostrar las personas de una cierta edad,\n"
  "3.-Mostrar los nombres de las personas cuya \n"
      "    letra inicial se haya digitado,\n"
  "4.-Salir del programa.\n");
     
   scanf("\n %d", &opcion);
         
   switch (opcion)
   {
      case 1:
         printf("\nLista de personas:\n");
            for (i=0; i<j; i++)
               printf(" %s\n", personas[i].nombre);
                  goto lazo;
      case 2:
         printf("\nEscriba la edad en anios: \n");
         scanf(" %d", &anios);
         printf(" Personas de %d anios: \n", anios);
         k = 0;
         for (i=0; i<j; i++)
         {
            if (personas[i].edad==anios)
            {
               printf(" %s\n", personas[i].nombre);
               k++;
            }
         }
         if (k == 0)
            printf(" No hay personas de %d anios.\n", anios);
         goto lazo;
      case 3:
         printf("Escriba la letra inicial de un nombre: \n");
         scanf(" %c", &inicial);
         k = 0;
       printf(" Nombres con letra inicial \'%c': \n", inicial);
         for (i=0; i<j; i++)
         {
            if (personas[i].nombre[0]==inicial)
            {
               printf(" %s\n", personas[i].nombre);
               k++;
            }
         }
         if (k == 0)
   printf("No hay nombres con letra inicial \'%c'.\n", inicial);
         goto lazo;
      case 4:
         break;
      default:
         printf("...Por favor, vuelva a intentar.");
         goto lazo;  
   }  
   getchar();
   return 0;
}                    


       .........Saludos!
 



   
 


23-Jun-2012 21:14
Pablo Rampa

El siguiente ejercicio:

5.6.iv)
  Mejorar la base de datos de ficheros (ejemplo 53) para que no permita introducir tamaños incorrectos (números negativos) ni nombres de fichero vacíos.

/*---------------------------*/
/*  Ejemplo en C nº 53:      */
/*  C053.C                   */
/*                           */
/*  Tabla con muchos struct  */
/*  y menu para manejarla    */
/*                           */
/*  Curso de C,              */
/*    Nacho Cabanes          */
/*---------------------------*/


#include <stdio.h>
#include <string.h>

struct
{
  char nombreFich[41];     /* Nombre del fichero */
  unsigned long tamanyo;   /* El tamaño en bytes */
} fichas[1000];

int numeroFichas=0;  /* Número de fichas que ya tenemos */
int i;               /* Para bucles */
int opcion;          /* La opcion del menu que elija el usuario */
char textoTemporal[40]; /* Para cuando preguntemos al usuario */
unsigned long numeroTemporal;

main()
{
 do
 {
   /* Menu principal */
   printf("Escoja una opcion:\n");
   printf("1.- Aniadir datos de un nuevo fichero\n");
   printf("2.- Mostrar los nombres de todos los ficheros\n");
   printf("3.- Mostrar ficheros que sean de mas de un cierto tamanio\n");
   printf("4.- Ver datos de un fichero\n");
   printf("5.- Salir\n");

   /* Para evitar problemas con datos mal introducidos,
      leemos con "gets" y luego lo filtramos con "sscanf" */
   gets (textoTemporal);
   sscanf(textoTemporal, "%d", &opcion);

   /* Hacemos una cosa u otra según la opción escogida */
   switch(opcion)
   {
      case 1: /* Añadir un dato nuevo */
        if (numeroFichas < 1000)   /* Si queda hueco */
        {
           printf("Introduce el nombre del fichero: ");
           lazo: gets(fichas[numeroFichas].nombreFich);
           if (strcmp(fichas[numeroFichas].nombreFich, "") == 0)
           {
               printf("Introduce el NOMBRE del fichero: ");
               goto lazo;
           }
           printf("Introduce el tamanio en KB: ");
           lazo1: gets(textoTemporal);
           if (strchr(textoTemporal, '-') != 0)
           {
       printf("Introduce el TAMANIO (numero positivo) en KB: ");
               goto lazo1;
            }
             sscanf(textoTemporal,"%ld",&fichas[numeroFichas].tamanyo);
            /* Y ya tenemos una ficha más */
            numeroFichas++;
         }
         else   /* Si no hay hueco para más fichas, avisamos */
            printf("Maximo de fichas alcanzado (1000)!\n");
            break;
      case 2: /* Mostrar todos */
         for (i=0; i<numeroFichas; i++)
            printf("Nombre: %s; Tamanio: %ld Kb\n",
                   fichas[i].nombreFich, fichas[i].tamanyo);
            break;
      case 3: /* Mostrar según el tamaño */
      printf("A partir de que tamanio quieres que te muestre?");
         gets(textoTemporal);
         sscanf(textoTemporal, "%ld", &numeroTemporal);
         for (i=0; i<numeroFichas; i++)
            if (fichas[i].tamanyo >= numeroTemporal)
               printf("Nombre: %s; Tamanio: %ld Kb\n",
                   fichas[i].nombreFich, fichas[i].tamanyo);
            break;
      case 4: /* Ver todos los datos (pocos) de un fichero */
         printf("¿De que fichero quieres ver todos los datos?");
         gets(textoTemporal);
         for (i=0; i<numeroFichas; i++)
            if (strcmp(fichas[i].nombreFich,textoTemporal) == 0)
               printf("Nombre: %s; Tamanio: %ld Kb\n",
                    fichas[i].nombreFich, fichas[i].tamanyo);
            break;
      case 5: /* Salir: avisamos de que salimos */
         printf("Fin del programa\n");
         break;
      default: /* Otra opcion: no válida */
         printf("Opcion desconocida!\n");
         break;
      }
   }
   while (opcion != 5);  /* Si la opcion es 5, terminamos */
}

  .....Saludos, hasta el próximo ejercicio.


23-Jun-2012 22:25
Pablo Rampa

...Aquí está el siguiente:

Ej. 5.6.v:
 Ampliar la base de datos de ficheros (ejemplo 53) para que incluya una opción de búsqueda parcial, en la que el usuario indique parte del nombre y se muestre todos los ficheros que contienen ese fragmento (usando “strstr”).  


/*---------------------------*/
/*  Ejemplo en C nº 53:      */
/*  C053.C                   */
/*                           */
/*  Tabla con muchos struct  */
/*  y menu para manejarla    */
/*                           */
/*  Curso de C,              */
/*    Nacho Cabanes          */
/*---------------------------*/


#include <stdio.h>
#include <string.h>

struct
{
  char nombreFich[41];     /* Nombre del fichero */
  unsigned long tamanyo;   /* El tamaño en bytes */
} fichas[1000];

int numeroFichas=0;  /* Número de fichas que ya tenemos */
int i;               /* Para bucles */
int opcion;        /* La opcion del menu que elija el usuario */
char textoTemporal[40]; /* Para cuando preguntemos al usuario */
unsigned long numeroTemporal;

main()
{
 do
 {
   /* Menu principal */
   printf("Escoja una opcion:\n");
   printf("1.- Aniadir datos de un nuevo fichero\n");
   printf("2.- Mostrar los nombres de todos los ficheros\n");
   printf("3.- Mostrar ficheros que sean de mas de "
               "un cierto tamanio\n");
   printf("4.- Ver datos de un fichero\n");
   printf("5.- Buscar ficheros, digitando una parte "
                "del nombre\n");
   printf("6.- Salir\n");

   /* Para evitar problemas con datos mal introducidos,
      leemos con "gets" y luego lo filtramos con "sscanf" */
   gets (textoTemporal);
   sscanf(textoTemporal, "%d", &opcion);

   /* Hacemos una cosa u otra según la opción escogida */
   switch(opcion)
   {
      case 1: /* Añadir un dato nuevo */
         if (numeroFichas < 1000)   /* Si queda hueco */
         {
            printf("Introduce el nombre del fichero: ");
            lazo: gets(fichas[numeroFichas].nombreFich);
            if (strcmp(fichas[numeroFichas].nombreFich,"")==0)
            {
               printf("Introduce el NOMBRE del fichero: ");
               goto lazo;
            }
            printf("Introduce el tamanio en KB: ");
            lazo1: gets(textoTemporal);
            if (strchr(textoTemporal, '-') != 0)
            {
               printf("Introduce el TAMANIO "
                      "(numero positivo) en KB: ");
               goto lazo1;
            }
              sscanf(textoTemporal,"%ld",&fichas[numeroFichas].tamanyo);
            /* Y ya tenemos una ficha más */
            numeroFichas++;
         }
         else   /* Si no hay hueco para más fichas, avisamos */
            printf("Maximo de fichas alcanzado (1000)!\n");
            break;
      case 2: /* Mostrar todos */
         for (i=0; i<numeroFichas; i++)
            printf("Nombre: %s; Tamanio: %ld Kb\n",
                   fichas[i].nombreFich, fichas[i].tamanyo);
            break;
      case 3: /* Mostrar según el tamaño */
         printf("A partir de que tamanio quieres que "
                 "te muestre?");
         gets(textoTemporal);
         sscanf(textoTemporal, "%ld", &numeroTemporal);
         for (i=0; i<numeroFichas; i++)
            if (fichas[i].tamanyo >= numeroTemporal)
               printf("Nombre: %s; Tamanio: %ld Kb\n",
                   fichas[i].nombreFich, fichas[i].tamanyo);
            break;
      case 4: /* Ver todos los datos (pocos) de un fichero */
         printf("¿De que fichero quieres ver todos los datos?");
         gets(textoTemporal);
         for (i=0; i<numeroFichas; i++)
            if (strcmp(fichas[i].nombreFich, textoTemporal)==0)
               printf("Nombre: %s; Tamanio: %ld Kb\n",
                    fichas[i].nombreFich, fichas[i].tamanyo);
            break;
     case 5:/*Buscar ficheros, digitando una parte del nombre*/
         printf("Escribe algunas letras contenidas en el "
                 "nombre del fichero: ");
         gets(textoTemporal);
         for (i=0; i<numeroFichas; i++)
            if (strstr(fichas[i].nombreFich, textoTemporal)
                                             != NULL)
            printf("Nombre: %s; Tamanio: %ld Kb\n",
                    fichas[i].nombreFich, fichas[i].tamanyo);
            break;
      case 6: /* Salir: avisamos de que salimos */
         printf("Fin del programa\n");
         break;
      default: /* Otra opcion: no válida */
         printf("Opcion desconocida!\n");
         break;
      }
   }
   while (opcion != 6);  /* Si la opcion es 6, terminamos */
}




24-Jun-2012 10:41
Nacho Cabanes (+83)

Dos comentarios, Pablo:

a) Cuando lees un número y después un texto, en el teclado se introduce el número y se pulsa Intro, luego el texto y se vuelve a pulsar Intro. Si usas un "scanf("%d", ...", la variable numérica guardará el número... pero el Intro queda esperando en el buffer del teclado. Si lees un segundo número, no hay problema, porque se omite ese Intro, pero si lees una cadena, ese Intro es aceptable, porque representaría una cadena vacía.

Por eso, cuando lees primero un número y luego una cadena, tendrás que "absorber" el Intro. Una forma de hacerlo sería:

scanf("%d",...
getchar();
gets(...

En el caso del ejercicio 5.6.iii, el getchar no debe ir (conceptualmente) antes de leer el nombre, sino después de pedir la opción numérica.


b) No uses "goto". Conduce a programas muy poco legibles, y es evitable en un 99% de los casos. Casi cualquier cosa que hagas con un "for" la podrás hacer también de forma más elegante y más legible con un "while" o un "do-while".

En muchos centros de estudios, el uso injustificado de "goto" supone un suspenso inmediato. Desde luego, si fueras mi alumno, lo sería.  ;-)


27-Jun-2012 01:14
Pablo Rampa

Gracias, estimado Nacho, por su atención y disculpas por los GOTO. El GOTO me quedó del Basic, pero prometo borrarlo del set de instrucciones y sólo usarlo cuando ya no pueda más.

Aquí están otros ejercicios:

5.6.vi)
 Ampliar la base de datos de ficheros (ejemplo 53) para que se pueda borrar un cierto dato (habrá que “mover hacia atrás” todos los datos que había después de ese, y disminuir el contador de la cantidad de datos que tenemos).

/*---------------------------*/
/*  Ejemplo en C nº 53:      */
/*  C053.C                   */
/*                           */
/*  Tabla con muchos struct  */
/*  y menu para manejarla    */
/*                           */
/*  Curso de C,              */
/*    Nacho Cabanes          */
/*---------------------------*/

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

struct
{
  char nombreFich[41];     /* Nombre del fichero */
  unsigned long tamanyo;   /* El tamaño en bytes */
} fichas[1000];

int aux;
int numeroFichas=0; /* Número de fichas que ya tenemos */
int numeroFicha=0;  /*Número de cada ficha */
int i;              /* Para bucles */
int opcion;         /* La opcion del menu que elija el usuario */
char textoTemporal[40]; /* Para cuando preguntemos al usuario */
unsigned long numeroTemporal;

main()
{
  do
  {
   /* Menu principal */
   printf("\n  Escoja una opcion:\n");
   printf("1.- Aniadir datos de un nuevo fichero\n");
   printf("2.- Mostrar los nombres de todos los ficheros\n");
   printf("3.- Mostrar ficheros que sean de mas de un cierto tamanio\n");
   printf("4.- Ver datos de un fichero\n");
   printf("5.- Buscar ficheros, digitando una parte del nombre\n");
   printf("6.- Borrar un fichero\n");
   printf("7.- Salir\n");

   /* Para evitar problemas con datos mal introducidos,
      leemos con "gets" y luego lo filtramos con "sscanf" */
   gets (textoTemporal);
   sscanf(textoTemporal, "%d", &opcion);

   /* Hacemos una cosa u otra según la opción escogida */
   switch(opcion)
   {
      case 1: /* Añadir un dato nuevo */
         if (numeroFichas < 1000)   /* Si queda hueco */
         {
            printf("Introduce el nombre del fichero: ");
            lazo: gets(fichas[numeroFichas].nombreFich);
           if (strcmp(fichas[numeroFichas].nombreFich, "") == 0)
            {
               printf("Introduce el NOMBRE del fichero: ");
               goto lazo;
            }            
            printf("Introduce el tamanio en KB: ");
            lazo1: gets(textoTemporal);  
            if (strchr(textoTemporal, '-') != 0)
            {
       printf("Introduce el TAMANIO (numero positivo) en KB: ");
               goto lazo1;
            }
               sscanf(textoTemporal,"%ld",&fichas[numeroFichas].tamanyo);
            /* Y ya tenemos una ficha más */
            numeroFichas++;
         }
         else   /* Si no hay hueco para más fichas, avisamos */
            printf("Maximo de fichas alcanzado (1000)!\n");
            break;
      case 2: /* Mostrar todos */
         for (i=0; i<numeroFichas; i++)
            printf("Nombre: %s; Tamanio: %ld Kb\n",
                   fichas[i].nombreFich, fichas[i].tamanyo);
         break;
      case 3: /* Mostrar según el tamaño */
      printf("A partir de que tamanio quieres que te muestre?");
         gets(textoTemporal);
         sscanf(textoTemporal, "%ld", &numeroTemporal);
         for (i=0; i<numeroFichas; i++)
            if (fichas[i].tamanyo >= numeroTemporal)
               printf("Nombre: %s; Tamanio: %ld Kb\n",
                   fichas[i].nombreFich, fichas[i].tamanyo);
            break;
      case 4: /* Ver todos los datos (pocos) de un fichero */
         
         printf("De que fichero quieres ver todos los datos?");
         gets(textoTemporal);
         for (i=0; i<numeroFichas; i++)
           if (strcmp(fichas[i].nombreFich, textoTemporal) == 0)
               printf("Nombre: %s; Tamanio: %ld Kb\n",
                    fichas[i].nombreFich, fichas[i].tamanyo);
            break;
      case 5: /* Buscar ficheros, digitando una parte del nombre */
       printf("Escribe algunas letras contenidas en el nombre "
                "del fichero: ");
         gets(textoTemporal);
         for (i=0; i<numeroFichas; i++)
          if (strstr(fichas[i].nombreFich, textoTemporal)!=NULL)
            printf("Nombre: %s; Tamanio: %ld Kb\n",
                    fichas[i].nombreFich, fichas[i].tamanyo);
            break;
      case 6: /* Borrar un fichero */
         printf("Escriba el nombre del fichero a eliminar: ");
         gets(textoTemporal);
         for (i=0,numeroFicha=0; i<numeroFichas; i++,numeroFicha++)
         {
          if (strcmp(fichas[i].nombreFich, textoTemporal) == 0)
            {              
               for (i=numeroFicha; i<numeroFichas; i++)
               {
           strcpy(fichas[i].nombreFich, fichas[i+1].nombreFich);
                   fichas[i].tamanyo = fichas[i+1].tamanyo;
               }
               numeroFichas--;
            }
        }
        break;
      case 7: /* Salir: avisamos de que salimos */
         printf("Fin del programa\n");
         getchar();
         break;
      default: /* Otra opcion: no válida */
         printf("Opcion desconocida!\n");
      }
  }
  while (opcion != 7);
}



5.6.vii)
Mejorar la base de datos de ficheros (ejemplo 53) para que se pueda modificar un cierto dato a partir de su número (por ejemplo, el dato número 3). En esa modificación, se deberá permitir al usuario pulsar Intro sin teclear nada, para indicar que no desea modificar un cierto dato, en vez de reemplazarlo
por una cadena vacía.

/*---------------------------*/
/*  Ejemplo en C nº 53:      */
/*  C053.C                   */
/*                           */
/*  Tabla con muchos struct  */
/*  y menu para manejarla    */
/*                           */
/*  Curso de C,              */
/*    Nacho Cabanes          */
/*---------------------------*/

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

struct
{
  char nombreFich[41];     /* Nombre del fichero */
  unsigned long tamanyo;   /* El tamaño en bytes */
} fichas[1000];


int numeroFichas=0; /* Número de fichas que ya tenemos */
int numeroFicha=0;  /*Número de cada ficha */
int i;              /* Para bucles */
int opcion;         /* La opcion del menu que elija el usuario */
char nuevoDato[40];
char textoTemporal[40]; /* Para cuando preguntemos al usuario */
unsigned long numeroTemporal;

main()
{
  do
  {
    /* Menu principal */
    printf("\n  Escoja una opcion:\n");
    printf("1.- Aniadir datos de un nuevo fichero\n");
    printf("2.- Mostrar los nombres de todos los ficheros\n");
    printf("3.- Mostrar ficheros que sean de mas de un cierto tamanio\n");
    printf("4.- Mostrar los datos de un fichero\n");
    printf("5.- Buscar ficheros, digitando una parte del nombre\n");
    printf("6.- Borrar un fichero\n");
    printf("7.- Modificar un fichero\n");
    printf("8.- Salir\n");

    /* Para evitar problemas con datos mal introducidos,
      leemos con "gets" y luego lo filtramos con "sscanf" */
    gets (textoTemporal);
    sscanf(textoTemporal, "%d", &opcion);

    /* Hacemos una cosa u otra según la opción escogida */
    switch(opcion)
    {
      case 1: /* Añadir un dato nuevo */
         if (numeroFichas < 1000)   /* Si queda hueco */
         {
        printf("Introduce el nombre del fichero: ");          
            gets(fichas[numeroFichas].nombreFich);
        while (strcmp(fichas[numeroFichas].nombreFich, "") == 0)
               printf("Introduce el NOMBRE del fichero: ");
                                                     
            printf("Introduce el tamanio en KB: ");
            gets(textoTemporal);                    
            while (strchr(textoTemporal, '-') != 0)
       printf("Introduce el TAMANIO (numero positivo) en KB: ");
            sscanf(textoTemporal,"%ld",&fichas[numeroFichas].tamanyo);
            /* Y ya tenemos una ficha más */
            numeroFichas++;
            break;
         }
         else   /* Si no hay hueco para más fichas, avisamos */
            printf("Maximo de fichas alcanzado (1000)!\n");
            break;
      case 2: /* Mostrar todos */
         for (i=0; i<numeroFichas; i++)
            printf("Nombre: %s; Tamanio: %ld Kb\n",
                   fichas[i].nombreFich, fichas[i].tamanyo);
         break;
      case 3: /* Mostrar según el tamaño */
      printf("A partir de que tamanio quieres que te muestre?");
         gets(textoTemporal);
         sscanf(textoTemporal, "%ld", &numeroTemporal);
         for (i=0; i<numeroFichas; i++)
            if (fichas[i].tamanyo >= numeroTemporal)
               printf("Nombre: %s; Tamanio: %ld Kb\n",
                   fichas[i].nombreFich, fichas[i].tamanyo);
            break;
      case 4: /* Ver todos los datos (pocos) de un fichero */
         printf("De que fichero quieres ver todos los datos?");
         gets(textoTemporal);
         for (i=0; i<numeroFichas; i++)
           if (strcmp(fichas[i].nombreFich, textoTemporal) == 0)
               printf("Nombre: %s; Tamanio: %ld Kb\n",
                       fichas[i].nombreFich, fichas[i].tamanyo);
         break;
         
   case 5: /* Buscar ficheros, digitando una parte del nombre */
       printf("Escribe algunas letras contenidas en el nombre "
                "del fichero: ");
       gets(textoTemporal);
       for (i=0; i<numeroFichas; i++)
          if (strstr(fichas[i].nombreFich, textoTemporal)!=NULL)
          printf("Nombre: %s; Tamanio: %ld Kb\n",
                 fichas[i].nombreFich, fichas[i].tamanyo);
       break;
    case 6: /* Borrar un fichero */
       printf("Escriba el nombre del fichero a eliminar: ");
       gets(textoTemporal);
       numeroFicha=0;
       for (i=0; i<numeroFichas; i++)
       {
          if (strcmp(fichas[i].nombreFich, textoTemporal) == 0)
          {              
             for (i=numeroFicha; i<numeroFichas; i++)
             {
       strcpy(fichas[i].nombreFich, fichas[i+1].nombreFich);
               fichas[i].tamanyo = fichas[i+1].tamanyo;
             }
             numeroFichas--;
          }
       numeroFicha++;    
       }
       break;
    case 7: /* Modificar un fichero */
       printf("Escriba el numero del fichero a modificar: ");
       gets(textoTemporal);
       sscanf(textoTemporal, "%ld", &numeroTemporal);
       printf("Escriba el nuevo nombre del fichero: ");
       gets(textoTemporal);
       if (strcmp(textoTemporal, "") != 0)
          sscanf(textoTemporal, "%s",
                     fichas[numeroTemporal].nombreFich);
       printf("Escriba el nuevo tamanio del fichero: ");
       gets(textoTemporal);
       if (strcmp(textoTemporal, "") != 0)
          sscanf(textoTemporal, "%ld",
                       &fichas[numeroTemporal].tamanyo);
       break;  
    case 8: /* Salir: avisamos de que salimos */
       printf("Fin del programa\n");
       getchar();
       break;
     
   default: /* Otra opcion: no válida */
      printf("Opcion desconocida!\n");
   }
 }
 while (opcion != 8);
}



5.6.viii)
 Ampliar la base de datos de ficheros (ejemplo 53) para que se
 permita ordenar los datos por nombre. Para ello, deberás buscar
 información sobre algún método de ordenación sencillo, como el
 "método de burbuja" (en el siguiente apartado tienes algunos),
 y aplicarlo a este caso concreto.

/*---------------------------*/
/*  Ejemplo en C nº 53:      */
/*  C053.C                   */
/*                           */
/*  Tabla con muchos struct  */
/*  y menu para manejarla    */
/*                           */
/*  Curso de C,              */
/*    Nacho Cabanes          */
/*---------------------------*/

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

struct
{
  char nombreFich[41];     /* Nombre del fichero */
  unsigned long tamanyo;   /* El tamaño en bytes */
} fichas[1000];


int numeroFichas=0; /* Número de fichas que ya tenemos */
int numeroFicha=0;  /*Número de cada ficha */
int i, j, k;              /* Para bucles */
int opcion;         /* La opcion del menu que elija el usuario */
char aux[40][20];
char nombres[40][20],nombre[40][20];
char textoTemporal[40]; /* Para cuando preguntemos al usuario */
unsigned long numeroTemporal;

main()
{
  do
  {
    /* Menu principal */
    printf("\n  Escoja una opcion:\n");
    printf("1.- Aniadir datos de un nuevo fichero\n");
    printf("2.- Mostrar todos los ficheros ordenados alfabeticamente\n");
    printf("3.- Mostrar ficheros que sean de mas de un cierto tamanio\n");
    printf("4.- Mostrar los datos de un fichero\n");
    printf("5.- Buscar ficheros, digitando una parte del nombre\n");
    printf("6.- Borrar un fichero\n");
    printf("7.- Modificar un fichero\n");
    printf("8.- Salir\n");

    /* Para evitar problemas con datos mal introducidos,
      leemos con "gets" y luego lo filtramos con "sscanf" */
    gets (textoTemporal);
    sscanf(textoTemporal, "%d", &opcion);

    /* Hacemos una cosa u otra según la opción escogida */
    switch(opcion)
    {
      case 1: /* Añadir un dato nuevo */
         if (numeroFichas < 1000)   /* Si queda hueco */
         {
         printf("Introduce el nombre del fichero: ");          
            gets(fichas[numeroFichas].nombreFich);
        while (strcmp(fichas[numeroFichas].nombreFich, "") == 0)
            {
               printf("Introduce el NOMBRE del fichero: ");
               gets(fichas[numeroFichas].nombreFich);
            }
            printf("Introduce el tamanio en KB: ");
            gets(textoTemporal);                    
            while (strchr(textoTemporal, '-') != 0)
       printf("Introduce el TAMANIO (numero positivo) en KB: ");
            sscanf(textoTemporal,"%ld",&fichas[numeroFichas].tamanyo);
            /* Y ya tenemos una ficha más */
            numeroFichas++;
            break;
         }
         else   /* Si no hay hueco para más fichas, avisamos */
            printf("Maximo de fichas alcanzado (1000)!\n");
            break;
      case 2: /* Mostrar todos ordenados alfabeticamente*/
         for (i=0; i<numeroFichas; i++)
         {
            for (i=0; i<numeroFichas; i++)
               sscanf(fichas[i].nombreFich, "%s", nombres[i]);
               
            for (i=0; i<(numeroFichas-1); i++)
            {
               for (j=(i+1); j<numeroFichas; j++)
               {
                  if (strcmp(nombres[i], nombres[j])>0)
                  {
                     strcpy(aux[k], nombres[i]);
                     strcpy(nombres[i], nombres[j]);
                     strcpy(nombres[j], aux[k]);
                  }
              }
            }
         }
         printf("\n Los nombres ordenados son:\n");  
         for (i=0; i<numeroFichas; i++)
            printf("%d. %s\n", i+1, nombres[i]);
         break;
      case 3: /* Mostrar según el tamaño */
      printf("A partir de que tamanio quieres que te muestre?");
         gets(textoTemporal);
         sscanf(textoTemporal, "%ld", &numeroTemporal);
         for (i=0; i<numeroFichas; i++)
            if (fichas[i].tamanyo >= numeroTemporal)
               printf("Nombre: %s; Tamanio: %ld Kb\n",
                   fichas[i].nombreFich, fichas[i].tamanyo);
            break;
      case 4: /* Ver todos los datos (pocos) de un fichero */
         printf("De que fichero quieres ver todos los datos?");
         gets(textoTemporal);
         for (i=0; i<numeroFichas; i++)
           if (strcmp(fichas[i].nombreFich, textoTemporal) == 0)
               printf("Nombre: %s; Tamanio: %ld Kb\n",
                       fichas[i].nombreFich, fichas[i].tamanyo);
         break;
         
   case 5: /* Buscar ficheros, digitando una parte del nombre */
       printf("Escribe algunas letras contenidas en el nombre "
                "del fichero: ");
       gets(textoTemporal);
       for (i=0; i<numeroFichas; i++)
          if (strstr(fichas[i].nombreFich, textoTemporal)!=NULL)
          printf("Nombre: %s; Tamanio: %ld Kb\n",
                 fichas[i].nombreFich, fichas[i].tamanyo);
       break;
    case 6: /* Borrar un fichero */
       printf("Escriba el nombre del fichero a eliminar: ");
       gets(textoTemporal);
       numeroFicha=0;
       for (i=0; i<numeroFichas; i++)
       {
          if (strcmp(fichas[i].nombreFich, textoTemporal) == 0)
          {              
             for (i=numeroFicha; i<numeroFichas; i++)
             {
           strcpy(fichas[i].nombreFich, fichas[i+1].nombreFich);
               fichas[i].tamanyo = fichas[i+1].tamanyo;
             }
             numeroFichas--;
          }
       numeroFicha++;    
       }
       break;
    case 7: /* Modificar un fichero */
       printf("Escriba el numero del fichero a modificar: ");
       gets(textoTemporal);
       sscanf(textoTemporal-1, "%ld", &numeroTemporal);
       printf("Escriba el nuevo nombre del fichero: ");
       gets(textoTemporal);
       if (strcmp(textoTemporal, "") != 0)
          sscanf(textoTemporal, "%s",
                     fichas[numeroTemporal].nombreFich);
       printf("Escriba el nuevo tamanio del fichero: ");
       gets(textoTemporal);
       if (strcmp(textoTemporal, "") != 0)
          sscanf(textoTemporal, "%ld",
                       &fichas[numeroTemporal].tamanyo);
       break;  
    case 8: /* Salir: avisamos de que salimos */
       printf("Fin del programa\n");
       getchar();
       break;
     
   default: /* Otra opcion: no válida */
      printf("Opcion desconocida!\n");
   }
 }
 while (opcion != 8);
}

  .....Saludos!


29-Jun-2012 00:31
Pablo Rampa

Ultimo ejercicio del Capítulo 5:

5.7
  Un programa que cree un array de 7 números enteros y lo ordene
con cada uno de estos tres métodos, mostrando el resultado de los pasos intermedios.

Metodo BURBUJA (creciente)
  Intercambiar cada pareja consecutiva que no esté ordenada.
 
#include <stdio.h>
int main()
{
    int i, j, aux;
    int numeros[7];
         
    printf("\n Escriba 7 numeros: \n");
    for (i=0; i<7; i++)
       scanf("%d", &numeros[i]);     // Obtiene los números.
    for (i=0; i<(6); i++)            // Lazos ascendentes.
    {
       for (j=(i+1); j<7; j++)
       {
          if (numeros[i] > numeros[j])  // Si el numero[j] es menor que el numero[i],
          {                       // intercambia sus posiciones.
             aux = numeros[i];
             numeros[i] = numeros[j];
             numeros[j] = aux;
          }
       }
    }
    printf("\n Los numeros quedan ordenados asi: \n");  
                                            // Salida ordenada.
    for (i=0; i<=6; i++)
       printf("%d,  ", numeros[i]);
    getchar();
    getchar();
    return 0;    
 }
 

 Metodo BURBUJA (decreciente)

#include <stdio.h>
int main()
{
    int i=0, j=0, aux;
    int numeros[7];
         
    printf("\n Escriba 7 numeros: \n");
    for (i=0; i<7; i++)
       scanf("%d", &numeros[i]);
       
    for (i=7; i>=1; i--)          // Lazos descendentes.
    {
       for (j=1; j<=i; j++)
       {
          if (numeros[j-1] > numeros[j])
          {
             aux = numeros[j-1];        // Intercambia valores.
             numeros[j-1] = numeros[j];
             numeros[j] = aux;
          }
       }
    }
    printf("\n Los numeros quedan ordenados asi: ");  
    for (i=0; i<=6; i++)
       printf("%d,  ", numeros[i]);  // Salida ordenada.
    getchar();
    getchar();
    return 0;    
 }


  Método de SELECCION DIRECTA
   En cada pasada busca el menor, y lo intercambia al final de la pasada.
 
#include <stdio.h>
int main()
{
    int i, j, aux;
    int numeros[7];
    int menor;
         
    printf("\n Escriba 7 numeros: \n");
    for (i=0; i<7; i++)
       scanf("%d", &numeros[i]);
    // En cada pasada busca el menor y lo establece al final de la pasada.
    for (i=0; i<7; i++)   // para i=0 hasta n-1
    {
                                                     
       for (j=(i+1); j<=7; j++) // para j=i+1 hasta n
       {
        if (numeros[j] < numeros[i]) // Si numeros[i] no es menor que numeros[j].
          {
                                               
                                                   
                                                 
             aux = numeros[i];  
                         // intercambia las parejas comparadas.
             numeros[i] = numeros[j];
             numeros[j] = aux;
         
          }
       }
    }        
    printf("\n Los numeros quedan ordenados asi: ");  
                                            // Salida ordenada.
    for (i=0; i<7; i++)
        printf("%d,  ", numeros[i]);
    getchar();
    getchar();
    return 0;    
 }  
 

       
  Metodo de INSERCION DIRECTA  
      Compara cada elemento con los anteriores -que ya están ordenados- y lo desplazar hasta su posición correcta).

#include <stdio.h>
int main()
{
    int i, j, aux;
    int numeros[7];
         
    printf("\n Escriba 7 numeros: \n");
    for (i=0; i<7; i++)
       scanf("%d", &numeros[i]);
    for (i=1; i<7; i++)         //Para i=1 hasta n-1
    {
       for (j=0; j<i; j++)
       {
          if (numeros[i] < numeros[j])
          {
             aux = numeros[i];  
                        //Intercambia  numeros[i] y numeros[j].
             numeros[i] = numeros[j];
             numeros[j] = aux;
          }
       }
    }
    printf("\n Los numeros quedan ordenados asi: ");  
    for (i=0; i<7; i++)
       printf("%d,  ", numeros[i]);        // Salida ordenada.
    getchar();
    getchar();
    return 0;    
 }                      

     Me da gusto haber terminado los ejercicios propuestos del
Capítulo 5. Cuando recién comenzaba el capítulo, pensé que me tardaría más tiempo terminarlo. Pero, gracias a la paciencia del Profesor Nacho y alguna que otra ayuda recibida de los partici-
pantes del Foro, por fin lo he logrado. Y siento que he apren-
dido bastante, gracias al Curso y a las "jaladas de oreja" del Profesor.
 
               P-|
  ...Saludos!


30-Jun-2012 21:24
Pablo Rampa

Tenía una deuda con el Profesor. Y esto es a manera de petición de disculpas por el abUSO de GOTO, mal uso del GETS y SCANF, y el uso innecesario del acento circunflejo con el operador conjunto:

Ej:5.5.2.i)
       Ampliar el programa del apartado 5.5.1, para que almace-
ne datos de hasta 100 canciones. Deberá tener un menú que permi-
ta las opciones: añadir una nueva canción, mostrar el título de todas las canciones, buscar la canción que contenga un cierto texto (en el artista o en el título).

       
#include <stdio.h>
#include <string.h>

struct  discoMP3
{
  char nombreArtista[40];
  char tituloCancion[40];
  int duracionenSegundos;
  float tamanioFicheroKB;
}cancion[100], auxiliarT[100];
 
int main()
{
  char c, texto[20];
  int  i=0, j=0, n=0;
   
  printf("\"STRUCT\" para guardar hasta 100 canciones\n");
  printf("    de un disco en formato MP3");
  printf("\n\n\n\tLista de OPCIONES:");
  printf("\n\n Pulse A para agregar una nueva cancion.");
  printf("\n Pulse T para mostrar el titulo de todas las canciones.");
  printf("\n Pulse B para buscar la cancion que tenga un cierto ");
  printf("\n            texto en el artista o en el titulo.");
  printf("\n Pulse S para salir del programa.");
  do
  {
     do
     {
        printf("\n\n\t Por favor, \n"
             "\t introduzca la OPCION que desee: ");
        c = getchar(); /* Aquí da algún
                   problemilla con las                          
     }            opciones no válidas.*/
 while (c!='A' && c!='T' && c!='B' && c!='S');                  
     switch (c)
     {
        case 'A':
           do
           {
              printf("\n\n Cuantas canciones va a guardar? :  ");
              scanf("%d", &n);
              getchar();              /* Absorbe el "intro" previo. */
           }
           while(n <= 0 || n > 100);
           for (i=0; i<n; i++)
           {
              printf("\n\n\tTrack No. %d\n", i+1);
              printf(" Nombre del artista: ");
              gets(cancion[i].nombreArtista);
              printf(" Titulo de la cancion: ");
              gets(cancion[i].tituloCancion);
              sprintf(auxiliarT[i].tituloCancion,
                   "%s", cancion[i].tituloCancion);
              printf(" Duracion en segundos: ");
              scanf("%d", &cancion[i].duracionenSegundos);
              printf(" Espacio de memoria en KB: ");
              scanf("%g", &cancion[i].tamanioFicheroKB);
              getchar();               /* Absorbe el "intro" previo. */
           }
           printf("\n\n\n\tSALIDA:");
           for (i=0; i<n; i++)
           {
              printf("\n\n\tTrack No. %d\n", i+1);
              printf("Artista: %s", cancion[i].nombreArtista);
              printf("\nTitulo: %s", cancion[i].tituloCancion);
              printf("\nDuracion: %d segundos",
                             cancion[i].duracionenSegundos);
              printf("\nMemoria: %g KB\n",
                             cancion[i].tamanioFicheroKB);
           }
           break;
               
        case 'T':
           puts("\nLista de canciones:\n");
           for (i=0; i<n; i++)
              printf("%d.%s\n", (i+1), auxiliarT[i].tituloCancion);
           if (n == 0)
              printf(" No se encontro ninguna cancion.");
           getchar();    
           break;
        case 'B':
           getchar();             /*  Absorbe "intro" previo. */
           printf("\n Escriba una palabra o un pequenio texto\n "
                " que se encuentre en el nombre del artista\n "
                " o en el titulo de la cancion: ");
          /*getchar();                O aquí. */
          gets(texto);
          j = 0;
          for (i=0; i<n; i++)
          {
             if (strstr(cancion[i].nombreArtista, texto) ||
                     strstr(cancion[i].tituloCancion, texto)!=NULL)
            {
               printf("\n Se encontro coincidencia en el Track %d\n",i+1);
               j++;
            }  
         }
         if (j == 0)
            printf("\n No se encontro ninguna coincidencia.");
             
         getchar();
         break;
      }
   }
   while (c != 'S');
   getchar();
   return 0;
}                        
                       
 
     
    .....Saludos a todos y en especial al Profesor Nacho.


02-Jul-2012 18:12
Rudi Merlos Carrion

Hola Pablo, antes que nada enhorabuena por tu trabajo y gracias a ti y a Nacho porque siempre estáis ahí cuando tengo alguna duda.

Necesito una aclaración sobre este código (5.6.viii). Concretamente sobre el método burbuja. He logrado controlar los tres métodos de ordenación con enteros pero cuando tocamos las cadenas se me va de las manos. Intenté hacer este programa y le asigné dos variables (char aux[40], nombres[40]) y no funcionaba, fue entonces cuando consulté tu código y vi que tú las asignas como (char aux[40][20], nombre[40][20]) y así sí que funciona.

¿Porque?

Gracias


03-Jul-2012 11:05
Nacho Cabanes (+83)

Ten en cuenta que un número entero es

int x;

mientras que una cadena de caracteres en C es un array:

char nombre[40];

Por tanto, un array de 20 enteros sería

int x[20];

y un array de 20 cadenas sería

char nombre[40][20];

Lo que no es necesario es char aux[40][20], porque te basta con una única cadena auxiliar para intercambiar valores, no necesitas 20 cadenas distintas, así que sería char aux[40].


03-Jul-2012 11:26
oscar gomez

cordial saludo profesor, una duda con respecto a la explicacion que le das a nuestro compañero, es que dices:

un array de 20 cadenas sería

char nombre[40][20];

perdona si estoy mal , no seria char nombre[20][40], indicando con ello un array de 20 cadenas cada una con un maximo de 40 caracteres, o es que el orden de los corchetes en c no alteran el concepto, gracias por la explicacion que me des.


04-Jul-2012 03:33
Pablo Rampa

  Al profesor,
gracias por sus oportunas y efectivas respuestas.
 
  A Rudi, que te digo si ya te respondió el Profesor.

  Con respecto a lo que dice Oscar, yo también lo creo así,
y más bien fue un "lapsus lingüis" del Profesor.

  A todos un saludo cordial!


26-Jul-2012 16:54
Nacho Cabanes (+83)

Voy a intentar sacar tiempo durante este final del mes de julio para revisar el curso de C: corregir alguna de las erratas (poco importantes, afortunadamente) que habéis ido descubriendo los usuarios del curso, ampliar un poco con problemas frecuentes (como mezclar scanf para número y para cadenas), y, de paso, incluir alguna solución más a ejercicios propuestos.

Para esto último, no pondré todas las soluciones, sino una de cada bloque, o las que tengan especial dificultad, y para algunas de ellas, tomaré las propuestas de Pablo Rampa, dando créditos, como ya se puede ver aquí:

http://www.nachocabanes.com/c/curso/c_soluciones.php#050102a

Espero poder lanzar la correspondiente versión PDF a principios de agosto.


31-Jul-2012 00:37
teresa yaneth campos perez

úna pregunta por que utilizas el arreglo de nombreMes como una tabla nombreMes[12][80]que no solo vas a trabajar  con los 12 meses del año? no entiendo por q el de [80] y esta instruccion aun no la entiendo =S nombreMes[i-1]); por q menos 1 =/


31-Jul-2012 15:56
Nacho Cabanes (+83)

Si tienes esas dudas, necesitas releer el tema 5 del curso (ten en cuenta que estos son los ejercicios de ese tema):

http://www.aprendeaprogramar.com/mod/resource/view.php?id=321

- Lo de "i-1" es porque en los arrays se empieza a contar desde cero.

- Lo de nombreMes[12][80] es porque son 12 "bloques" de hasta 80 caracteres cada uno (12 cadenas de un máximo de 79 letras).






(No se puede continuar esta discusión porque tiene más de dos meses de antigüedad. Si tienes dudas parecidas, abre un nuevo hilo.)