[C con Clase] Problema queda sin responder

Steven Davidson srd4121 en njit.edu
Dom Jul 11 09:22:01 CEST 2010


Hola Luis,

Luis Arenas wrote:
> 
> 1.- este codigo qeu tengo cuando lo corro en devc me funciona bien
> hasta que elijo la opcion dos, se abre ingreso la marca eltipo todo
> bien hasta elprecio cuando tiene que grabar en el archivo no graba y
> se queda pegado hasta qe aparec un cuadro qeu dice que elprograma no
> responde.
> 

A mí me ejecuta correctamente, pero es cuestión de suerte, porque tienes 
varios errores al leer y escribir. Te los comento en el código fuente.

> 
> 2.-como ven en  el codigo cree un vector de estructuras la idea es
> que cuando se quiera buscar un producto desde el archivo se copie
> todo lo que este ahi en el vector de estructuras pero como hago eso
> ???

Como el fichero es de texto, tendrás que interpretar la información para 
lo que quieres. Por ahora, existen tres cadenas de caracteres y un 
número entero por cada registro. Por consiguiente, no hace falta 
interpretar esta información, pero sí el número entero que representa el 
precio. Afortunadamente, 'fscanf()' ya realiza esta tarea para nosotros.

Lo que sí debes tener en cuenta es el formato u organización interna del 
fichero. Deberías elegir caracteres que sirvan para marcar el fin y el 
comienzo de cada parte de la información guardada. Por ejemplo, 
podríamos diseñar el siguiente formato:

[TIPO];[MARCA];[DESCRIPCIÓN];[PRECIO]\n

De esta forma, cada registro que contiene la información del producto se 
guarda en cada línea, indicada por el carácter '\n'. Por ejemplo,

Carne;Burger King;Corteza de árbol en forma de carne;2\n
Patatas Fritas;Doritos;Corteza de árbol frita;4\n

Existen varias formas de implementar esta lectura. Podemos leer cada 
línea de texto y guardarla en una cadena de caracteres, usando 
'fgets()'. Posteriormente, podemos usar 'strtok()' para conseguir un 
puntero a cada cadena, que nos interesa, para procesarla; debemos tener 
en cuenta los caracteres delimitadores (o separadores), pero sin 
guardarlos en los campos.

En el caso de los tres primeros campos, cada cadena es copiada tal y 
como aparece. Pero para el último campo, tenemos que interpretar esta 
última cadena para poder conseguir un valor numérico de tipo 'int'. Para 
esto, invocamos 'sscanf()'. Por ejemplo,

char szLinea[256];
char *ptr;
...
sscanf( ptr, "%d", &produc[0].precio );

Para más información acerca de estas funciones, consulta la referencia 
en nuestra página yendo a: 
http://c.conclase.net/librerias/index.php?ansilib=stdio#inicio  y a 
http://c.conclase.net/librerias/index.php?ansilib=string#inicio

> 

Veamos el código fuente.

> #include <stdio.h>
> #include <stdlib.h>
> 
> 
> struct {
>        char tipo_producto;
>        char marca_producto;
>        char descripcion;
>        int precio;
>        }vec[50],produc[1];
>       
>       
> int m,opc;

No es recomendable definir variables globales. Define éstas localmente, 
en 'main()'.

> main(){

En C/C++, debes indicar el tipo de retorno 'int' explícitamente.

>      
> m=1;
> while(m==1){
> printf("  **************************************************************************\n");
> printf("  **          Bienvenido al software de precio Sagrado Corazon            **\n");
> printf("  **************************************************************************\n\n\n\n\n\n");
> printf("                  1.- Consultar Precio Producto\n");
> printf("                  2.- Ingresar Nuevo Producto\n");
> printf("                  3.- Salir \n\n\n");
> printf("Ingrese su opcion:\n");
> scanf("%d",&opc);
> switch(opc){
>            
>       case 1:
>            break;
>       case 2:
>            FILE *pf;
>       if ((pf = fopen("productos.txt","a+")) == NULL) {
>             printf("Error abriendo el archivo\n");
>             exit(1);} 
>            system("cls");
>            printf("Ingrese nombre producto");
>            printf("\n\n Ingrese el tipo de producto\n");
>            scanf("%s",&produc[0].tipo_producto);
>            printf("\n\n Ingrese Marca del producto\n");
>            scanf("%s",&produc[0].marca_producto);
>            printf("\n\n Ingrese descripcion del producto\n");
>            scanf("%s",&produc[0].descripcion);

El uso de 'scanf()' es incorrecto para estos campos. Estás indicando que 
cada campo es una cadena de caracteres, cuando en verdad cada uno es de 
tipo 'char'. Por lo tanto, deberías indicar "%c" y no "%s" en 'scanf()'.

Claro está, lo más seguro es que el error es de diseño y realmente 
quieres que esos tres campos representen cadenas de caracteres. Esto es,

struct producto_t
{
   char tipo_producto[30];
   char marca_producto[30];
   char descripcion[60];
   int precio;
};

Las lecturas con 'scanf()' serán:

scanf( "%s", produc[0].tipo_producto );
scanf( "%s", produc[0].marca_producto );
scanf( "%s", produc[0].descripcion );

>            printf("\n\n Ingrese el PRECIO\n");
>            scanf("%d",&produc[0].precio);
>            printf("\n\nProducto ingresado");
>            fprintf(pf,"%c",produc[0].tipo_producto);
>            fprintf(pf,"%c",produc[0].marca_producto);
>            fprintf(pf,"%c",produc[0].descripcion);

Esto es correcto con el diseño original, pero con el nuevo, tendrás que 
usar "%s" para indicar que son cadenas - terminadas en nulo.

>            fprintf(pf,"%c",produc[0].precio);

Esto no es correcto. Este campo es de tipo 'int', y por tanto, debes 
usar el especificador %d. Esto es,

fprintf( pf, "%d", produc[0].precio );

>       
>       
>        }

Deberías retornar un número entero. Se retorna 0 (cero) para indicar que 
el programa ha terminado con éxito.


Espero haber aclarado las dudas.

Steven





Más información sobre la lista de distribución Cconclase