carlosabcs18, un par de detalles:
* El código decóralo con las etiquetas GeSHi... elige el lenguaje adecuado para que el texto se formatee correctamente.
* En C++ existe la clase string, la cual permite sustituir las cadenas de C (char*). Usar esta clase tiene varias ventajas: Simplifica el código, se evitan varios errores tontos, no tienes que pegarte con punteros...
// Version C
char producto[20];
strcpy( producto, "Coche" );
// Versión C++
std::string producto = "Coche";
* No es recomendable usar variables globales. Las variables globales pueden ser hasta peligrosas. No merece la pena ahorrarse dos líneas de código. En pocas ocasiones es necesario usar una variable global.
* En C++ existen los denominados contenedores. El contenedor más popular es "vector", el cual te permite gestionar listas no ordenadas de elementos. Con esta clase puedes sustituir tu variable "vendedores". Sustituir un arreglo C por un contenedor tiene la ventaja de que, por ejemplo, te puedes despreocupar del número de elementos en la lista, el contenedor se redimensiona por si solo cuando sea necesario.
std::vector< vendedor > vendedores;
// Insertar nuevo vendedor
// ----------
vendedor nuevo_vendedor;
// dar valores al nuevo vendedor
// ...
vendedores.push_back( nuevo_vendedor );
// Vaciar la lista de vendedores
vendedores.clear( );
// Saber el numero de vendedores dados de alta
std::cout << vendedores.size( ) << std::endl;
* En C++ suele ser recomendable no anidar clases, eso es más propio de C y normalmente dificulta la legibilidad del código:
struct direccion
{
std::string calle;
int numero;
std::string urbanizacion;
};
struct vendedor
{
int dni;
std::string nombre;
std::string apellidos;
direccion dir;
std::vector< producto > prod;
// La siguiente variable ahora sobra, el contenedor ya tiene esta informacion
// int n_prod;
};
* No pongas varias instrucciones en la misma línea. Al compilador le va a dar igual que las instrucciones estén todas seguidas o en diferentes líneas, el programa va a ocupar prácticamente lo mismo... pero la legibilidad del código se resiente. No te proporciona ningún beneficio y perjudica el mantenimiento del codigo:
// opcion mala
cout<< "Producto: "; fflush(stdin); gets(vendedores[nv].prod.producto);
// opcion buena
cout<< "Producto: ";
fflush(stdin);
gets(vendedores[nv].prod.producto);
* No uses fflush sobre stdin. fflush está pensado únicamente para bufferes de salida, no de entrada. El resultado puede ser indeterminado... además, ya puestos a usar C++, usa cin en vez de gets y compañía.
Ampliando el tema de fflush... si ya de por si no es recomendable mezclarlo con stdin... menos aún usarlo junto a cin. cin es una clase y es independiente de stdin... actúan sobre el mismo buffer, pero no tienen por qué trabajar igual, puedes acabar con problemas de sincromismo.
Si quieres limpiar el buffer de cin lo mejor es hacer algo tal que:
// Limpiar todo el buffer
cin.ignore( std::numeric_limits< std::streamsize >::max( ) );
// Limpiar el buffer hasta el primer salto de línea.
cin.ignore( std::numeric_limits< std::streamsize >::max( ), '\n' );
Y, por supuesto, no es recomendable mezclar accesos a cin con el uso de gets, scanf, ...
* Me he fijado en que la clase "producto" tiene un "subtotal"... este campo es el resultado de la operación cantidad*precioVenta. Este planteamiento presenta el inconveniente de que si en algún momento actualizas uno de estos dos campos y no recalculas "subtotal" entonces tendrás una inconsistencia.
A mi modo de ver sería recomendable calcular este valor sobre la marcha cuando se requiera mediante un método:
struct producto
{
std::string producto;
int cantidad;
float precioVenta;
float Subtotal( ) const
{
return static_cast< float >( cantidad ) * precioVenta;
}
};
"static_cast" lo uso para convertir "cantidad" a float... prefiero los cast de C++ a los de C, son más seguros y más sencillos de localizar en el código.
* Procura que las variables signifiquen algo:
int n,i,v,w,nv,el_v,dni;
Si tu te encuentras esta línea en un programa cualquiera... ¿sabrías decir cual es la finalidad de cada una de esas variables? Costaría un poco, ¿verdad?
Y si en vez de esa línea te encuentras una tal que:
int num_vendedores, id_vendedor_datos, id_vendedor_productos, id_vendedor_eliminar;
¿Se entendería mejor el código?
Si este ejemplo no es lo suficientemente claro tengo otro:
// opcion 1
h = x * i * ( 1.0 + d );
// opcion 2
total = precio_unitario * unidades * ( 1.0 + iva );
Bueno, hasta aquí mis consejos prácticos... tengo más, así que si te quedas con ganas luego te comento.
Ahora vamos con tus "errores":
void e_vendedor( int x, int num)
{
for(int i=x; i<(num-1); i++)
vendedor=vendedor[i+1];
num--;
}
// ...
e_vendedor(el_v-1,n);
"num" se pasa por valor, luego "num--" no tendrá efecto sobre "n". Si pretendes modificar "v" dentro de "e_vendedor" tienes que pasar la variable por referencia:
void e_vendedor( int x, int& num)
Y el otro error:
void buscar( int dni)
{
int band = 0;
if(dni>0)
{
for(int i=0; i<dni; i++) // <<------ AQUI!!!!
{
if(vendedor.dni==dni)
{
cout<<"\n\n La direccion de "<<vendedor.nombres<<" "
<<vendedor.apellidos<<" es : "
<<vendedor.dir.calle<<" "<<vendedor.dir.numero<<" "<<vendedor.dir.urbanizacion<<endl ;
band = 1 ;
break;
}
}
}
else
cout<<"\n\tRegistro vacio..!";
if(band==0)
cout<<"\n\n\tEl vendedor no fue encontrado! "<<endl;
}
¿por qué asumes que "dni" lo puedes usar para recorrer la lista de vendedores? Si usas un arreglo de C tienes que pasar a la función la cantidad de vendedores en la lista. Si pasas un DNI que no exista el código va a leer fuera del arreglo y eso te va a dar problemas.