Bueno ya que estamos, subo un programa recién sacado del horno... todavía tengo que solucionar el ordenamiento. Lo demás funciona perfecto.
//Este programa fue realizado por el mejor programador de todos los tiempos, yo.
//Después de largas horas de duro trabajo y tras llegar a un colapso neuronal, pude terminarlo.
//Si bien tengo un pequeño inconveniente en una función, el laburo es magnífico.
//Tres Hip Hip Hurra para mí: "Hip Hip Hurra, Hip Hip Hurra, Hip Hip Hurra."
//Preparación para final de Informática I.
//Lista Simplemente Enlazada + Manejo de Archivo + Ordenamiento.
//Librerías.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define NOMBRE 10
//Estructura.
struct nodo {
char nombre[NOMBRE];
int inventario;
int stock;
struct nodo *Siguiente;
};
//Prototipos de las Funciones.
void ImprimirLista ( struct nodo * );
struct nodo * BuscarNodo ( struct nodo * );
void ModificarNodo ( struct nodo * );
void InsertarNodoEsp ( struct nodo * );
void InsertarNodoIzq ( struct nodo ** );
void BorrarNodo ( struct nodo ** );
void Menu ( );
struct nodo * CrearNodo ( );
struct nodo *Registrar ( struct nodo *);
void GuardarLista ( struct nodo * );
void Lista( struct nodo **, struct nodo * );
void RecuperarLista ( struct nodo ** );
int BorrarArchivo ( void );
void OrdenarLista ( struct nodo ** );
//Main.
int main ( void )
{
int opcion;
struct nodo *Cabeza=NULL; //Inicialmente la lista se encuentra vacia.
RecuperarLista ( &Cabeza );
Menu ( );
do
{
printf("\nOpción: ");scanf("%d",&opcion);
switch(opcion)
{
case 1:
InsertarNodoIzq ( &Cabeza );
break;
case 2:
InsertarNodoEsp ( Cabeza );
break;
case 3:
BuscarNodo ( Cabeza );
break;
case 4:
ModificarNodo ( Cabeza );
break;
case 5:
BorrarNodo ( &Cabeza );
break;
case 6:
ImprimirLista ( Cabeza );
break;
case 7:
GuardarLista ( Cabeza );
break;
case 8:
OrdenarLista ( &Cabeza );
break;
case 9:
printf("\n...:::FIN DEL PROGRAMA:::...\n\n");
exit (-1);
break;
default:
system("clear");
printf("\n...:::OPCION NO VALIDA:::...\n");
break;
} //Fin del switch.
Menu ( );
} //Fin del do.
while( opcion != 9 );
return 0;
}
//Función que inserta un nodo a izquierda del primer nodo. Es decir, el último nodo
//ingresado va a ser la cola izquierda de nuestra lista y el primer nodo ingresado
//será su cola derecha.
void InsertarNodoIzq ( struct nodo **Enlace )
{
struct nodo *Nuevo; //Puntero a la estructura nodo.
Nuevo = Registrar ( CrearNodo ( ) ); //Se crea un espacio de memoria.
if ( Nuevo == NULL ) //No se pudo reservar memoria.
{
printf("\nNo se pudo asignar memoria\n");
return;
}
//Doble enlace.
Nuevo -> Siguiente = *Enlace; //El nodo creado ahora apunta al nodo que anteriormente
//era el primer nodo de la lista.
*Enlace = Nuevo; //El puntero enlace ( cabeza ) ahora apunta al nuevo nodo creado.
}//Fin de la función
//Esta función también inserta un nodo pero lo hace después del nodo elegido por el
//usuario (buscado a partir del nombre del cliente).
void InsertarNodoEsp ( struct nodo *P )
{
struct nodo *Nuevo;
if( P == NULL ) //La lista se encuentra vacía.
{
printf("\nLista vacia\n");
return;
}
BuscarNodo ( P );
if( P == NULL )
printf ("\nEl elemento buscado no se encuentra en la lista.\n");
else{
printf("\nIngrese los campos del nodo a insertar\n");
Nuevo = Registrar ( CrearNodo ( ) );;
if( Nuevo == NULL ) //No se pudo reservar memoria.
printf("\nNo se pudo asignar memoria\n");
else{ //Se creo el nuevo nodo, por ende realizamos el doble enlace.
//Cuatro nodos a modificar.
Nuevo -> Siguiente = P -> Siguiente; //El nuevo nodo apunta al nodo de su derecha.
P -> Siguiente = Nuevo; //El nodo que está a la izquierda apunta al nuevo nodo
//(que está a su derecha).
} //Fin del else interno.
} //Fin del else externo.
} //Fin de la función.
//Busca un nodo a partir del nombre ingresado por el usuario.
struct nodo * BuscarNodo ( struct nodo * P )
{
char name[NOMBRE];
printf("\nIngrese el elemento que desea buscar:\n");
printf("\nNombre: "); scanf("%s",name);
//Búsqueda del nodo correspondiente al nombre ingresado.
while( ( P != NULL ) && ( strcmp ( name , P -> nombre ) != 0 ) )
P = P -> Siguiente;
return P;
}
void ModificarNodo ( struct nodo * P )
{
if( P == NULL ) //La lista se encuentra vacía.
{
printf("\nLista vacía. No hay nodos para modificar\n");
return;
}
P = BuscarNodo ( P );
if ( P == NULL )
printf("\nEl nombre no se encuentra en la lista\n");
else
{
printf("\nModifique los campos del nodo.\n");
printf ("\nStock: "); scanf ("%d" , &P->stock );
}
}
void BorrarNodo ( struct nodo ** Cabeza )
{
struct nodo *Actual, *Anterior;
char name[NOMBRE];
if ( *Cabeza == NULL ) //Lista vacía.
{
printf("\nLista vacía. No hay nodos para borrar\n");
return;
}
Actual = *Cabeza;
printf("\nIngrese el elemento que desea buscar:\n");
printf("\nNombre: "); scanf("%s",name);
while ( Actual != NULL && strcmp ( name , Actual -> nombre ) != 0 )
{
Anterior = Actual;
Actual = Actual -> Siguiente;
}
if ( Actual == NULL ) //El nombre seleccionado no se encuentra en la lista.
printf("\nEl elemento no se encuentra en la lista\n");
else{
if ( Actual == *Cabeza )
*Cabeza = Actual -> Siguiente;
else
Anterior -> Siguiente = Actual -> Siguiente;
free ( Actual ); //Libero el espacio de memoria del nodo borrado.
printf("Nodo borrado\n");
} //Fin del else externo.
} //Fin de la función.
//Crea un nuevo nodo.
struct nodo *CrearNodo ( void )
{
struct nodo *Crear;
Crear = ( struct nodo * ) malloc ( sizeof ( struct nodo ) ); //Creo el nuevo nodo.
if ( Crear == NULL ) //No se pudo almacenar memoria para el nuevo nodo.
return NULL;
//Doble enlace.
Crear -> Siguiente = NULL;
return Crear; //Retorna el nodo creado.
}
struct nodo *Registrar ( struct nodo *Reg )
{
//Se ingresan los campos del nodo.
printf ("\nIngrese nombre: "); scanf ("%s", Reg -> nombre );
printf ("\nIngrese numero de inventario: "); scanf("%d",&Reg->inventario);
printf ("Ingrese Stock: "); scanf ("%d",&Reg->stock);
return Reg;
}
//Menú.
void Menu(void)
{
printf ("\n...:::MENU PRINCIPAL:::...\n");
printf ("1 - Agregar nodo a izquierda del nodo cabeza.\n");
printf ("2 - Agregar nodo en un lugar específico.\n");
printf ("3 - Buscar nodo\n");
printf ("4 - Modificar nodo\n");
printf ("5 - Borrar nodo.\n");
printf ("6 - Mostrar lista.\n");
printf ("7 - Guardar lista.\n");
printf ("8 - Ordenar lista.\n");
printf ("9 - Salir\n");
}
//Imprime lista.
void ImprimirLista ( struct nodo *PAD )
{
if ( PAD == NULL ) //La lista se encuentra vacía.
{
printf("\nLista vacía.\n");
return;
}
//Existe la lista.
printf("\n...:::LISTA:::...\n\n");
while ( PAD != NULL ){ //Imprime la lista.
printf("Nombre: %s ", PAD -> nombre );
printf("Inventario: %d ", PAD -> inventario);
printf("Stock: %d --> ", PAD -> stock);
PAD = PAD -> Siguiente;
} //Fin del while.
}
//La siguiente función guarda la lista en un archivo con formato .txt.
void GuardarLista ( struct nodo * Actual )
{
FILE *fd;
fd = fopen ("practicando.txt","wb+");
if ( fd == NULL ){ //No se pudo abrir el archivo.
printf ("\nFallo al abrir el archivo.\n");
return;
}
while ( Actual != NULL ){
//Transcribe los datos de cada nodo en el archivo.
fwrite ( Actual , sizeof (struct nodo) , 1 , fd );
Actual = Actual -> Siguiente; //Nos movemos al siguiente nodo.
}
fclose ( fd ); //Cierra el archivo.
printf ("\nLista guardada en el archivo.\n");
}
//Crea lista.
void Lista( struct nodo **Cabeza, struct nodo *Actual )
{
struct nodo *Nuevo;
Nuevo = CrearNodo ( );
Nuevo -> inventario = Actual -> inventario;
strcpy ( Nuevo->nombre , Actual -> nombre );
Nuevo -> stock = Actual -> stock;
Nuevo -> Siguiente = *Cabeza;
*Cabeza = Nuevo;
}
//Recupera la lista a partir del archivo.
void RecuperarLista ( struct nodo **Cabeza )
{
FILE *Lee;
struct nodo datos;
int ba;
ba = BorrarArchivo ( );
if ( ba == 2) {
//Abre el archivo para lectura.
Lee = fopen ("practicando.txt","rb");
if( Lee == NULL )
printf("\nNo se pudo abrir el archivo.\n");
else {
fread ( &datos , sizeof ( struct nodo) , 1 , Lee );
while ( !feof ( Lee ) ) //Mientras no llegue al final del archivo...
{
Lista ( Cabeza, &datos );
fread ( &datos , sizeof ( struct nodo) , 1 , Lee );
}
fclose (Lee);
}
}
}
//Borra o no el archivo practicando.txt
int BorrarArchivo ( void )
{
int opcion;
printf ("\nIndique que desea hacer:\n1- Borrar archivo.\n2- Continuar con los datos cargados.\n");
printf ("\nOpción:\t"); scanf ("%d", &opcion);
if ( opcion == 1 )
remove ("practicando.txt");
else if ( opcion == 2 )
printf ("\nDatos recuperados.\n");
else BorrarArchivo ( ); //Recursividad.
return opcion;
}
//Ordena la lista según el nombre del cliente.
void OrdenarLista ( struct nodo **Cabeza )
{
struct nodo *Actual, *Anterior, *Aux;
Anterior = *Cabeza;
Actual = Anterior -> Siguiente;
while ( Actual != NULL ) {
if ( strcmp ( Actual -> nombre , Anterior -> nombre ) < 0 ){ //Si el nodo Actual es
//menor al nodo Anterior...
//Intercambio de nodos.
Aux = Actual; Actual = Anterior; Anterior = Aux;
//Generar Lista.
Lista ( &Actual , Anterior );
}
Actual = Actual -> Siguiente;
Anterior = Anterior -> Siguiente;
}
}