Deberías aprender a leer los errores que te da el compilador. Tu código tiene un montón de errores:
tanto nombre como descripción han sido definidos como un array de enteros... si intentas tratar esto como una lista de strings lo vas a pasar mal.
Ahora, tanto 'nombre' como 'descripcion' permiten almacenar 30 strings diferentes, cada uno con una longitud máxima de 49 caracteres.
Vamos a ver, 'nombre', 'descripcion', 'cantidad' y 'precio' van siempre juntos... ¿por qué no los agrupas en una estructura? El código va a quedar mucho más bonito y legible... además, no es prudente usar funciones con muchos parámetros, por lo que interesa reducirlos al máximo:
Con esto, las funciones ahora quedan un poco más legibles:
Esto aún puede mejorar un poco más, dado que tanto "ventas" como "impresion" van a recorrer toda la lista de artículos, no hace falta pasar 'X':
Y aún se le puede dar una vuelta de rosca más. Dado que el arreglo de artículos debe ir siempre acompañado del total de artículos, parece lógico agrupar estos dos elementos en una nueva estructura:
Con lo que ahora las funciones quedan más limpias todavía:
Mejor así, no?
¿Qué significa 'x'? ¿y 'c'? no son nombres 'válidos' porque no aportan información acerca de su finalidad. Es complicado seguir un código con variables sin sentido aparente. Hay que facilitar la lectura del código al máximo.
Por ejemplo, 'x' podría llamarse 'idArticulo' y 'c' lo podrías renombrar por 'totalArticulos'.
Si las funciones no tienen 'return algo', entonces deberían estar declaradas como 'void funcion':
Además, en C, si una función no está prensada para que reciba argumentos, hay que indicarlo poniendo 'void' entre los paréntesis:
En C, los strings son punteros, por lo que sobra ese '&' que tienes ahí
Según este código... cada venta se asocia a un cliente... además este cliente puede adquirir un número indeterminado de artículos... este diseño no te va a permitir nunca guardar un historial de pedidos. Aprovechando la infraestructura que te he comentado, se podría modificar para adaptarla a estos requisitos:
He aprovechado también a introducir dos 'defines' porque no me gustan los literales metidos a pelo en el código.
Con este diseño conseguimos que cada cliente tenga su propia lista de artículos, aunque no le saques partido a dicho detalle en esta aplicación.
¿Es necesario hacer estos cálculos aquí?
Asumiendo que sí, no es un buen sistema porque la llamada a "impresion" tiene demasiados argumentos... imagínate el lío si intercambias por error dos argumentos. Entre otras cosas puede que no seas capaz de ver el error tras muchas horas de sufrimiento.
Apoyándonos nuevamente en el diseño que hemos ido realizando, esto se puede mejorar sustancialmente:
Hemos añadido nuevos campos a las estructuras... ahora ya podemos actualizar el código de la función:
Fíjate lo sencilla que ha quedado ahora la llamada a "impresion".
Si miras el código, verás que en el bucle uso el puntero "Articulo* articulo = &venta->articulos[ i ]". El puntero lo uso únicamente para reducir la cantidad de código a escribir... si no usase este puntero el código quedaría tal que:
Parece obvio que el primer código es más legible.
El flujo de tu programa es deficiente.
"lectura" llama a "ventas" y este a su vez a "impresion". Esta cadena de llamadas debería estar controlada desde el "main". Los motivos son varios, pero tampoco es plan de escribir una tesis con este programa. Es importante intentar reducir la dependencia entre funciones.
El código final con los cambios aplicados:
Código (cpp) [Seleccionar]
int nombre[30];
int descripcion[30];
tanto nombre como descripción han sido definidos como un array de enteros... si intentas tratar esto como una lista de strings lo vas a pasar mal.
Código (c) [Seleccionar]
char nombre[30][50];
char descripcion[30][50];
Ahora, tanto 'nombre' como 'descripcion' permiten almacenar 30 strings diferentes, cada uno con una longitud máxima de 49 caracteres.
Código (c) [Seleccionar]
float ventas(int Nombre[30],int Descripcion[30],int Cantidad[30],float Precio[30],int X,int C);
float impresion(int Name[30],int Descr[30],int Cant[30],float Price[30],int X1,int C1,float Precioto[30],float subto,float tax,float Total,float Altotal);
Vamos a ver, 'nombre', 'descripcion', 'cantidad' y 'precio' van siempre juntos... ¿por qué no los agrupas en una estructura? El código va a quedar mucho más bonito y legible... además, no es prudente usar funciones con muchos parámetros, por lo que interesa reducirlos al máximo:
Código (c) [Seleccionar]
// Definición de la estructura
typedef struct
{
char nombre[ 50 ];
char descripcion[ 50 ];
int cantidad;
float precio;
} Articulo;
// ...
// Declaramos un array de 30 artículos
Articulo articulos[ 30 ];
// Acceso a datos del articulo 10
articulos[ 9 ].cantidad = 10;
Con esto, las funciones ahora quedan un poco más legibles:
Código (c) [Seleccionar]
float ventas( Articulo *articulos, int X, int C );
float impresion( Articulo *articulos, int X1, int C1, float Precioto[30], float subto, float tax, float Total, float Altotal );
Esto aún puede mejorar un poco más, dado que tanto "ventas" como "impresion" van a recorrer toda la lista de artículos, no hace falta pasar 'X':
Código (c) [Seleccionar]
float ventas( Articulo *articulos, int C );
float impresion( Articulo *articulos, int C1, float Precioto[30], float subto, float tax, float Total, float Altotal );
Y aún se le puede dar una vuelta de rosca más. Dado que el arreglo de artículos debe ir siempre acompañado del total de artículos, parece lógico agrupar estos dos elementos en una nueva estructura:
Código (c) [Seleccionar]
typedef struct
{
Articulo lista[ 30 ];
int totalArticulos;
} Venta;
Con lo que ahora las funciones quedan más limpias todavía:
Código (c) [Seleccionar]
float ventas( Venta *venta );
float impresion( Venta *venta, float Precioto[30], float subto, float tax, float Total, float Altotal );
Mejor así, no?
Código (c) [Seleccionar]
int x=0,c=0;
¿Qué significa 'x'? ¿y 'c'? no son nombres 'válidos' porque no aportan información acerca de su finalidad. Es complicado seguir un código con variables sin sentido aparente. Hay que facilitar la lectura del código al máximo.
Por ejemplo, 'x' podría llamarse 'idArticulo' y 'c' lo podrías renombrar por 'totalArticulos'.
Código (c) [Seleccionar]
int lectura();
float ventas( ... );
float impresion( ... );
Si las funciones no tienen 'return algo', entonces deberían estar declaradas como 'void funcion':
Código (c) [Seleccionar]
void lectura();
void ventas( ... );
void impresion( ... );
Además, en C, si una función no está prensada para que reciba argumentos, hay que indicarlo poniendo 'void' entre los paréntesis:
Código (c) [Seleccionar]
void lectura( void );
void ventas( ... );
void impresion( ... );
Código (c) [Seleccionar]
printf("\nIngrese el nombre del cliente: ");
scanf("%s",&nombre[c]);
En C, los strings son punteros, por lo que sobra ese '&' que tienes ahí
Código (c) [Seleccionar]
printf("\nIngrese el nombre del cliente: ");
scanf("%s",nombre[c]);
Código (c) [Seleccionar]
do
{
printf("\nIngrese el nombre del cliente: ");
scanf("%s",&nombre[c]);
do
{
printf("\nIngrese descripcion del producto: ");
scanf("%s",&descripcion[x]);
printf("\nIngrese cantidad del producto: ");
scanf("%d",&cantidad[x]);
printf("\nIngrese precio individual: ");
scanf("%f",&precio[x]);
x++;
printf("\nIngresar otro producto? S/N ");
limprod=getch();
} while(limprod=='s'||limprod=='S');
ventas(nombre,descripcion,cantidad,precio,x,c);
printf("\nProcesar otro cliente? S/N");
lim=getch();
c++;
} while(lim=='s'||lim=='S');
Según este código... cada venta se asocia a un cliente... además este cliente puede adquirir un número indeterminado de artículos... este diseño no te va a permitir nunca guardar un historial de pedidos. Aprovechando la infraestructura que te he comentado, se podría modificar para adaptarla a estos requisitos:
Código (c) [Seleccionar]
#define MAX_LENGTH 50
#define MAX_ARTICULOS 30
typedef struct
{
char nombre[ MAX_LENGTH ];
char descripcion[ MAX_LENGTH ];
int cantidad;
float precio;
} Articulo;
typedef struct
{
char cliente[ MAX_LENGTH ];
Articulo articulos[ MAX_ARTICULOS ];
int numeroArticulos;
} Venta;
He aprovechado también a introducir dos 'defines' porque no me gustan los literales metidos a pelo en el código.
Con este diseño conseguimos que cada cliente tenga su propia lista de artículos, aunque no le saques partido a dicho detalle en esta aplicación.
Código (c) [Seleccionar]
float ventas(int Nombre[30],int Descripcion[30],int Cantidad[30],float Precio[30],int X,int C)
{
float precioto[30];
int n=0;
float subtotal=0,impuesto=0,total=0,altotal=0;
int cltotal=0;
for(n=0;n<X;n++)
{
precioto[n]=Cantidad[n]*Precio[n];
subtotal+=precioto[n];
}
impuesto=subtotal*0.07;
total=subtotal+impuesto;
altotal+=total;
impresion(Nombre,Descripcion,Cantidad,Precio,X,C,precioto,subtotal,impuesto,total,altotal);
}
¿Es necesario hacer estos cálculos aquí?
Asumiendo que sí, no es un buen sistema porque la llamada a "impresion" tiene demasiados argumentos... imagínate el lío si intercambias por error dos argumentos. Entre otras cosas puede que no seas capaz de ver el error tras muchas horas de sufrimiento.
Apoyándonos nuevamente en el diseño que hemos ido realizando, esto se puede mejorar sustancialmente:
Código (c) [Seleccionar]
typedef struct
{
char nombre[ MAX_LENGTH ];
char descripcion[ MAX_LENGTH ];
int cantidad;
float precio;
float total;
} Articulo;
typedef struct
{
char cliente[ MAX_LENGTH ];
Articulo articulos[ MAX_ARTICULOS ];
int numeroArticulos;
float subtotal;
float impuestos;
float total;
} Venta;
Hemos añadido nuevos campos a las estructuras... ahora ya podemos actualizar el código de la función:
Código (c) [Seleccionar]
void ventas( Venta* venta, float* totalAlmacen )
{
venta->subtotal = 0;
venta->impuestos = 0;
int i;
for( i = 0; i < venta->numeroArticulos; i++ )
{
Articulo* articulo = &venta->articulos[ i ];
articulo->total = articulo->cantidad * articulo->precio;
float impuestos = articulo->total * 0.07;
venta->subtotal += articulo->total;
venta->impuestos += impuestos;
}
venta->total = venta->subtotal + venta->impuestos;
*totalAlmacen += venta->total;
impresion( venta, totalAlmacen );
}
Fíjate lo sencilla que ha quedado ahora la llamada a "impresion".
Si miras el código, verás que en el bucle uso el puntero "Articulo* articulo = &venta->articulos[ i ]". El puntero lo uso únicamente para reducir la cantidad de código a escribir... si no usase este puntero el código quedaría tal que:
Código (c) [Seleccionar]
for( i = 0; i < venta->numeroArticulos; i++ )
{
Articulo* articulo = &venta->articulos[ i ];
venta->articulos[ i ].total = venta->articulos[ i ].cantidad * venta->articulos[ i ].precio;
float impuestos = venta->articulos[ i ].total * 0.07;
venta->articulos[ i ].subtotal += venta->articulos[ i ].total;
venta->articulos[ i ].impuestos += impuestos;
}
Parece obvio que el primer código es más legible.
El flujo de tu programa es deficiente.
"lectura" llama a "ventas" y este a su vez a "impresion". Esta cadena de llamadas debería estar controlada desde el "main". Los motivos son varios, pero tampoco es plan de escribir una tesis con este programa. Es importante intentar reducir la dependencia entre funciones.
El código final con los cambios aplicados:
Código (c) [Seleccionar]
#include <stdio.h>
#include <ctype.h>
#define MAX_LENGTH 50
#define MAX_ARTICULOS 30
typedef struct
{
char nombre[ MAX_LENGTH ];
char descripcion[ MAX_LENGTH ];
int cantidad;
float precio;
float total;
} Articulo;
typedef struct
{
char cliente[ MAX_LENGTH ];
Articulo articulos[ MAX_ARTICULOS ];
int numeroArticulos;
float subtotal;
float impuestos;
float total;
} Venta;
void lectura( Venta* venta );
void ventas( Venta* venta, float* totalAlmacen );
void impresion( Venta* venta, float totalAlmacen );
int main()
{
int x;
for( x = 0; x < 50; x++ )
printf("\n");
float totalAlmacen = 0;
Venta venta;
lectura( &venta );
ventas( &venta, &totalAlmacen );
impresion( &venta, totalAlmacen );
return 0;
}
void lectura( Venta* venta )
{
int i = 0;
printf("\nIngrese el nombre del cliente: ");
scanf("%s", venta->cliente );
char respuesta;
do
{
printf("\nIngrese descripcion del producto: ");
scanf("%s", venta->articulos[ i ].descripcion );
printf("\nIngrese cantidad del producto: ");
scanf("%d", &venta->articulos[ i ].cantidad );
printf("\nIngrese precio individual: ");
scanf("%f", &venta->articulos[ i ].precio );
i++;
printf("\nIngresar otro producto? S/N ");
scanf( " %c", &respuesta );
} while( tolower( respuesta ) == 's' );
venta->numeroArticulos = i;
}
void ventas( Venta* venta, float* totalAlmacen )
{
venta->subtotal = 0;
venta->impuestos = 0;
int i;
for( i = 0; i < venta->numeroArticulos; i++ )
{
Articulo* articulo = &venta->articulos[ i ];
articulo->total = articulo->cantidad * articulo->precio;
float impuestos = articulo->total * 0.07;
venta->subtotal += articulo->total;
venta->impuestos += impuestos;
}
venta->total = venta->subtotal + venta->impuestos;
*totalAlmacen += venta->total;
}
void impresion( Venta* venta, float totalAlmacen )
{
printf("\n");
printf(" Nombre del cliente: x %s x", venta->cliente );
printf("\n%-30s | %-10s | %-10s | %-10s",
"DESCRIPCION",
"CANTIDAD",
"PRECIO",
"TOTAL" );
int i;
for( i = 0; i < venta->numeroArticulos; i++ )
{
Articulo* articulo = &venta->articulos[ i ];
printf("\n%-30s | %10d | %10.2f | %10.2f",
articulo->descripcion,
articulo->cantidad,
articulo->precio,
articulo->total );
}
printf("\n\t\t%20s %6.2f", "SUBTOTAL:", venta->subtotal );
printf("\n\t\t%20s %6.2f", "ITBMS:", venta->impuestos );
printf("\n\t\t%20s %6.2f", "TOTAL A PAGAR:", venta->total );
printf("\n");
printf("\nTotal Vendido por el Almacen: %.2f", totalAlmacen );
}