Código C++:
Ver originalstruct persona lista[20];
int maxIdP = 0;
int lastP = 0;
int ind = 0;
¿Variables globales? Evítalas salvo que sea imperativo usarlas... y en un programa de 200 líneas dudo mucho que sea imprescindible tirar de variables globales.
Una forma de eliminar algunas variables globales:
Código C++:
Ver originalint getMaxIdP(){
static int maxIdp = 0;
return ++maxIdP;
}
Además, No tiene demasiado sentido que esperes a que el nuevo registro se añada definitamente a la lista para actualizar maxIdp... int, para el uso particular que tienen estos identificadores, tiene un rango lo suficientemente amplio como para poder desaprovechar valores.
Aunque también, puestos a simplificar el código, yo pasaría de los arreglos tipo C y consideraría el uso de contenedores. Como ventaja principal que no te tienes que preocupar del número de elementos en el contenedor. Hablando del número de elementos... ¿Compruebas en algún punto que no se intentan meter más de 20 elementos en la lista?
Por cierto, nota que en C++ no hace falta poner "struct" a la hora de declarar elementos de tipo "persona". Aunque compile no es necesario en C++... al no ser necesario podemos decir que no aporta absolutamente nada al código, luego lo mejor es eliminarlo para tener un código lo más limpio posible. Otro detalle respecto a este punto es que en C++, como norma general, las clases y estructuras se suelen nombrar con la primera letra en maýusculas. Es una pequeña pijotada pero ayuda a leer mejor el código.
¿De verdad es necesario que
menu se llame a sí misma de forma recursiva? ¿No conoces los bucles tipo
while o
do-while?
Código C++:
Ver originalvoid menu(){
while(true)
{
// ...
}
}
Y pasando un poco a la chicha del programa:
Código C++:
Ver originalpersona getRow(std::string xnom){
persona p;
for (int i=0; i< lastP; i++){
if(lista[i].nom == xnom){
p = lista[i];
break;
}
}
return p;
}
void updated(){
// ...
p = getRow(xnom);
std::cout << "\n Persona: " << p.id << " Nombre: " << p.nom << " Apellido: " << p.ape;
std::cout << "\n ¿Desea algún dato? Aceptar=1/Cancelar=2 :";
}
¿Por qué asumes que el usuario va a introducir un nombre válido? ¿No puede equivocarse?
Por otro lado... si tu idea es simplificar el código... ¿Por qué no dejas a la STL hacer su trabajo?
Código C++:
Ver original// Lo suyo sería devolver un puntero... si el puntero es nulo es que no se ha encontrado el registro.
persona* getRow(std::string xnom){
persona* toReturn = nullptr; // inicialización de puntero nulo
auto it = std::find_if(std::begin(lista),std::end(lista),
[&xnom](const presona& p)
{ return p.nom == xnom; });
if( it != std::end(lista) )
toReturn = &(*it); // it
return p;
}
Aun así tendrías que lidiar con situaciones como... ¿Qué sucede si el usuario únicamente quiere cambiar el apellido? Ahora mismo el programa te va a decir que la persona ya existe y no va a actualizarlo.
Para borrar elementos de la lista tienes problemas similares que deberías corregir.
Más posibles mejoras:
Código C++:
Ver originalbool check(const persona& p){
int num_reg = std::count_if(std::begin(lista),std::end(lista),
[&p](const persona& p2)
{ return p2.nom == p.nom; });
return num_reg > 0;
}
Código C++:
Ver originalbool create(const persona& p){
bool toReturn = false;
if(!check(p)){
// Esta línea...
lista[lastP] = p;
// ...con std::vector podría quedar tal que
lista.push_back(p);
lastP++; // Esto con contenedores no es necesario
upMaxIdP(); // Si haces caso de lo que te he dicho antes esta línea también sobra
toReturn = true;
}
return toReturn;
}
Y bueno aquí tienes algunas guías para mejorar tu código, el resto, dado que hay que tomar decisiones respecto al diseño, es cosa tuya.
PD.:
find_if,
count_if forman parte de la librería
algorithm.
Un saludo.