Problema con loop

Iniciado por jaxoR, 1 Marzo 2014, 20:04 PM

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

jaxoR

Bueno, estaba practicando con C antes de empezar la facultad, y quice hacer un programa en el cual se le pide al usuario que ingrese la cantidad de productos que quiere guardar en el programa y que luego se le pida escribir los nombres de los productos. Todo iba bien hasta la parte del for, en el cual solo puedo ingresar un producto y enseguida finaliza el programa. Nosé que es lo que hago mal:

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

int main()
{
    int i, j, x;
    printf("Ingrese el numero de productos que quiere cargar:\n");
    scanf("%d", &i);
    x = 0;

    char productos[i];

    for(j; j==i; j++);
    {
        x++;
        printf("Ingrese el nombre de su producto:\n");
        scanf("%s", &productos[x]);
    }

    return 0;
}

dmacias

Te hablo desde el mas puro desconocimiento, asi que no me tengas mucho en cuenta, pero quizas sea que j no tiene ningun valor????


int i, j, x;
for(j; j==i; j++);


Si no es por eso, pues lo siento jajaja, estoy aprendiendo y ando muy muy verde aun.

Un saludo

rir3760

Errores importantes hay dos:

* El primero como ya te comentaron esta en el bucle: no le das un valor inicial a la variable "j", la variable "x" sobra, la condición del bucle debe ser "j < i" y tienes un punto y coma demás justo antes del cuerpo del bucle.

* El segundo es utilizar un array de chars para almacenar las palabras cuando deberia ser un array de arrays de caracteres.

Otro detalle es utilizar un array de longitud variable ya que estos se soportan en C99 y son opcionales en C11. Para el caso puedes reservar memoria con malloc.

El programa con las correcciones:
#include <stdio.h>
#include <stdlib.h>

#define NUM_CHARS  128

int main(void)
{
   char (*palabra)[NUM_CHARS];
   int num_pals;
   int i;
   
   puts("Numero de productos:");
   if (scanf("%d", &num_pals) != 1)
      return EXIT_FAILURE;
   
   palabra = malloc(num_pals * sizeof *palabra);
   
   for (i = 0; i < num_pals; i++){
      printf("Nombre del producto no %d:\n", i + 1);
      scanf("%s", palabra[i]);
   }
   
   /* ... */
   
   free(palabra);
   return 0;
}


Por ultimo hay que evitar el uso de scanf con "%s" ya que tiene los mismos riesgos que gets (mejor utilizar fgets).

Un saludo
C retains the basic philosophy that programmers know what they are doing; it only requires that they state their intentions explicitly.
--
Kernighan & Ritchie, The C programming language

jaxoR

Hola rir, ya arregle todo lo del bucle, lo que no te entiendo es lo del Array. Soy nuevo con los arrays, y no entiendo cuando te referís a un array de arrays de carácteres, me darías un ejemplo?

rir3760

Cita de: wiD^ en  2 Marzo 2014, 05:22 AMSoy nuevo con los arrays, y no entiendo cuando te referís a un array de arrays de carácteres, me darías un ejemplo?
1) Cuando se manejan valores del mismo tipo en lugar de un montón de variables se utiliza un array, por ejemplo:
#include <stdio.h>
#include <stdlib.h>

#define NUM_ELEM 10

int main(void)
{
   int num[NUM_ELEM]; /* array de int */
   int i;
   
   for (i = 0; i < NUM_ELEM; i++){
      num[i] = i;
      printf("%d\n", num[i]);
   }
   
   return EXIT_SUCCESS;
}


2) En C una cadena se almacena en un array de caracteres. Por ejemplo:
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
   char palabra[] = "Jeremias"; /* array de caracteres */
   
   printf("%s\n", palabra);
   
   return EXIT_SUCCESS;
}


Combinando los puntos anteriores si tu programa debe procesar varias cadenas estas se almacenan en un array de cadenas y como las cadenas se almacenan en arrays de caracteres eso resulta en un array de arrays de caracteres:
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
   char pal[][5] = {
      "Hugo",
      "Paco",
      "Luis"
   };
   int num_pals = (int) (sizeof pal / sizeof pal[0]);
   int i;
   
   for (i = 0; i < num_pals; i++)
      printf("%s\n", pal[i]);
   
   return EXIT_SUCCESS;
}


El uso de sizeof lo veras mas adelante, esta ahí porque lo políticamente correcto es no indicar el numero de elementos de un array si se utiliza (como en el ejemplo) una lista de valores para inicializarlo.

Un saludo
C retains the basic philosophy that programmers know what they are doing; it only requires that they state their intentions explicitly.
--
Kernighan & Ritchie, The C programming language

leosansan


Como comentó tan certeramente rir3760, otra forma es con un array de longitud variable, una vez ingresado el número de palabras:

Código (cpp) [Seleccionar]

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

#define NUM_CHARS  128

int main(void)
{
  int num_pals;
  int i;

  puts("Numero de productos:");
  if (scanf("%d", &num_pals) != 1)
    return EXIT_FAILURE;
  while (getchar()!='\n');
 
  char palabra[num_pals][NUM_CHARS];

  for (i = 0; i < num_pals; i++){
    printf("Nombre del producto no %d:\n", i + 1);
    scanf("%s", palabra[i]);
   }
   /* ... */
   return EXIT_SUCCESS;
}


En realidad el formato que ha usado rir3760 para el scanf tan sólo asegura que la entrada es un número.

Me explico:

* si introduces as canta error.
* si introduces 12 todo O.K
* Si introduces 12as por error el scanf toma el 12 y de paso se salta otro scanf porque en  el llamado buffer o memoria intermedia queda el resto, en este caso la "as" que toma el siguiente scanf de forma automática. De ahí el uso del while para "limpiar" el buffer. Haz la prueba con él activado y desactivado y veras lo que sucede.

¿Qué habría entonces que hacer?. Sencillamente comprobar que la variable "num_pals" se corresponde con un entero y sólo un entero. Pero imagino que ya tendrás tiempo más adelante de ir viendo esos detallitos que parecen chorradas y que pueden arruinar un código que parecía impecable.


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



Yoel Alejandro

Más clara imposible la explicación de por qué se llama "array de arrays" de caracteres.

De acuerdo también con el aporte de leosansan de verificar la integridad del dato suministrado por el usuario, y limpiar el búfer de entrada descartando los caracteres encontrados hasta llegar al fin de línea.

Creo que no tengo aportes que hacer a este tema ... ya se ha dicho todo, al menos al nivel que requiere quién inició la pregunta.
Saludos, Yoel.
P.D..-   Para mayores dudas, puedes enviarme un mensaje personal (M.P.)

jaxoR

Muchisimas gracias a todos! Ya lo pude hacer andar a mi manera