![]() |
|
![]() PARADIGMA La paciencia es la fortaleza del dévil y la impaciencia la debilidad del fuerte..! Immanuel Kant |
![]() Otras pages:
|
Recuerda que las estructuras de datos estáticas, como arreglos requieren necesariamente definir tamaños fijados en tiempo de compilación, mientras que las estructuras dinámicas de datos se expanden o contraen a medida que sean requeridas para su proceso.
Las estructuras dinámicas de datos son colecciones de elementos llamados NODOS, intervinculados por medio de PUNTEROS que permiten estructuras con capacidad de variar su tamaño y ocupar solo la memoria necesaria, creadas y se destruidas durante la ejecución.
Tales nodos de la estructura, generalmente del tipo registro, se enlazan o encadenan de modo que se establece un vículo o puntero asociando a cada nodo, que apunta al nodo siguiente de la estructura.
Existen diferentes tipos de estructuras dinámicas de datos, siendo las más usadas:
Para programarla debemos recordar los siguientes conceptos...
LOS PUNTEROS
Con el fin de simplificar el manejo de punteros, se utilizan nombres de variables en lugar de direcciones, pues los nombres son simples de recordar. Aunque en la realidad, en la máquina cada posición de la pila de memoria tiene una dirección y un valor específico almacenado en esa posición.
Para almacenar un nuevo valor en memoria se asigna a una variable, y la computadora envía una dirección a la memoria seguida por el valor a almacenar en esa posición.
DECLARACION de PUNTEROS
Para declarar un tipo puntero se indica el tipo de valor que se almacenará en la posicion designada por el puntero. Así cada puntero apunta a una variable particular, que es otra posición de memoria.
Dado que el puntero es una variable que registra la dirección de otra variable almacenada en una celda de memoria, es preciso diferenciar entre las dos entidades implicadas en el apuntamiento:
C++, Usa el asterisco (*) que sigue a los nodos, para indicar que "apunta a"; es decir el tipo de dato es una variable puntero que puede contener una dirección a un tipo de dato llamado nodo.
EJEMPLO: Para simplificar el tema, se ha tomado una agenda elemental de dos campos, nombre y email al que se le asignan los mecanismos de altas, bajas, modificaciones y consultas, en el que se incluye los algoritmos de búsqueda.
//////////////////////////////////////////////////////// // C++BUILDER 5 LISTA SIMPLE CON ARCHIV0 // ListaPrograma.cpp Wilucha 17/09/98 // Graba sobre en archivo Simple.txt //--------------------------------------------------------------------------- #include < vcl.h > #include < fstream.h > #include < stdlib.h > #pragma hdrstop #include "ListaPrograma.h" #pragma package(smart_init) #pragma resource "*.dfm" //--------------------------------------------------------------------------- TMiFormulario *MiFormulario; struct MiNodo { char CampoNodoNombre[30]; char CampoNodoEmail[40]; int FlagNodoBaja; struct MiNodo *SiguienteNodo; }
La lista enlazada es una secuencia de nodos enlazados o conectados con el siguiente formando una estructura de datos dinámica. Tales nodos suelen ser normalmente registros y que no tienen un tamaño fijo.
La ventaja de una lista enlazada sobre un arreglo es que la lista enlazada puede crecer y decrecer en tamaño y que fácil insertar o suprimir un nodo en el centro de una lista enlazada.
La lista enlazada es una estructura muy versátil, cuyos algoritmos para inserción y eliminación de datos constan de dos pasos:
El que en su vida nunca fue necio, jamás fue sabio..!!
ARCHIVO SECUENCIAL en C++BUILDER
En archivos secuenciales de datos, es necesario establecer un área de buffer, donde la información se almacena temporalmente mientras se está transfiriendo entre la memoria de la computadora y el archivo de datos. Esta área de buffer permite leer y escribir información del archivo más rápidamente de lo que sería posible de otra manera.
La sintaxis para el área de buffer es: FILE *VariablePuntero;
Donde FILE es un tipo de dato estructurado que establece el área de buffer y VariablePuntero es la variable puntero que indica el principio de esta área. Tal puntero generalmente define un puntero a archivo secuencial, o simplemente como archivo secuencial.
struct UnaFicha { char CampoFichaNombre[30]; char CampoFichaEmail[40]; }; FILE *Archivo; UnaFicha MiFicha; //---------------------------------------------------------------------------
La gestión de un archivo, puede resumirse en las siguientes etapas:
Ej: fstream F ("Agenda", ios : :int | ios : :out );
Abrir un archivo existente y si no existe no lo crea
Ej: fstream F ("Agenda", ios : :nocreate );
Ej: ifstream F ("Agenda");
Ej: ofstream F ("Agenda");
Seekg( ): Se usa para determinar posicionamiento forzado:
Previo a ser creado o procesado el archivo de datos debe ser abierto, de modo de asociar el nombre de archivo con el área de buffer y especificar si se va a usar el archivo como sólo para lectura, o sólo para escritura, o para lectura / escritura.
La sintaxis para abrir el archivo es: VariablePuntero = fopen (NombreArchivo, ModoDeUso);
Donde NombreArchivo es la cadena que identifica el nombre del archivo y ModoDeUso es la manera en la que el archivo será utilizado y debe ser una de las cadenas de la siguiente tabla.
La función fopen retorna un puntero al principio del área de buffer asociada con el archivo si este se puedeabrir y caso contrario, retorna un valor NULL si no se puede abrir el archivo, por ejemplo si un archivo existente no ha sido encontrado.
Para terminar el archivo debe cerrarse al final de un programa, aplicando la función de biblioteca fclose.
La sintaxis para cerrar es: fclose(VariablePuntero);
//--------------------------------------------------------------------------- //BOTON PARA SALIR DEL FORMULARIO PRINCIPAL void __fastcall TMiFormulario::Salir1Click(TObject *Sender) { MiNodo *Auxiliar; Auxiliar=PrimerNodo; if(Application->MessageBox("Desea Salir","Atencion",MB_OKCANCEL)==IDOK) { Close(); Archivo=fopen("Simple.txt","wb"); while(Auxiliar != NULL) { strcpy(MiFicha.CampoFichaNombre,Auxiliar->CampoNodoNombre); strcpy(MiFicha.CampoFichaEmail,Auxiliar->CampoNodoEmail); fwrite(&MiFicha, sizeof(MiFicha),1,Archivo); Auxiliar=Auxiliar->SiguienteNodo; } fclose(Archivo); } }
Una vez realizadas todas las operaciones deseadas sobre el Archivo hay que cerrarlo.
Al cerrarlo se vacían los buffers y se guarda el Archivo en disco. Un Archivo se cierra mediante la función fclose(Archivo). Si todo va bien fclose devuelve un cero, si hay problemas devuelve otro valor.
Estos problemas se pueden producir si el disco está lleno, por ejemplo.
if (fclose(Archivo)!=0) printf( "Problemas al cerrar el Archivo\n" ); }
Esta es una tarea divertida, por que me recuerda cuando niño enganchaba un nuevo vagón en mi trencito de juguete..!!. Para ello es necesario tener en cuenta que...
Este proceso ha sido aplicado en el siguiente algoritmo..
//////////////////////////////////////////////////////// // C++BUILDER 5 LISTA SIMPLE CON ARCHIV0 // ListaPrograma.cpp Wilucha 17/09/98 // Graba sobre en archivo Simple.txt //--------------------------------------------------------------------------- *PrimerNodo,*NodoActual,*NuevoNodo,*UltimoNodo; MiNodo *FichaAuxiliar,FichaTrucha; int MensajePorBox,ParametroOrdenar,FlagBaja,Fila; int BuscarCodigo(AnsiString); void AltaDeNuevoNodo(char ParamNombre[30],char ParamEmail[40]) { NuevoNodo = new MiNodo[sizeof(MiNodo)]; strcpy(NuevoNodo->CampoNodoNombre,ParamNombre); strcpy(NuevoNodo->CampoNodoEmail,ParamEmail); NuevoNodo->FlagNodoBaja=0; NuevoNodo->SiguienteNodo=NULL; UltimoNodo=NuevoNodo; if(PrimerNodo==NULL) PrimerNodo=NuevoNodo; else { NodoActual=PrimerNodo; while(NodoActual->SiguienteNodo != NULL) NodoActual=NodoActual->SiguienteNodo; NodoActual->SiguienteNodo=NuevoNodo; } }
..Ojito observa que este proceso inserta nuevos nodos en la lista, pero no en el archivo..!!
PARADIGMA HUMANO
//--------------------------------------------------------------------------- __fastcall TMiFormulario::TMiFormulario(TComponent* Owner) : TForm(Owner) { } //--------------------------------------------------------------------------- void __fastcall TMiFormulario::FormActivate(TObject *Sender) { FlagBaja=0; } //--------------------------------------------------------------------------- void __fastcall TMiFormulario::FormCreate(TObject *Sender) { Archivo = fopen("Simple.txt","rb"); while(!feof(Archivo)) { fread(&MiFicha,sizeof(MiFicha),1,Archivo); if(!feof(Archivo)) AltaDeNuevoNodo(MiFicha.CampoFichaNombre,MiFicha.CampoFichaEmail); } fclose(Archivo); } //--------------------------------------------------------------------------- void __fastcall TMiFormulario::Altas1Click(TObject *Sender) { MiFormulario->Caption="INGRESO DE DATOS"; Panel->Visible=true; BotonGrabar->Visible=true; BotonLimpiar->Visible=true; BotonEliminar->Visible=false; BotonModificar->Visible=false; BoxNombre->Clear(); BoxEmail->Clear(); BoxNombre->SetFocus(); Simple1->Enabled=false; } //--------------------------------------------------------------------------- void __fastcall TMiFormulario::BotonLimpiarClick(TObject *Sender) { BoxNombre->Clear(); BoxEmail->Clear(); BoxNombre->SetFocus(); }
PARADIGMA HUMANO
Por supuesto que los nodos dados de alta están vacios..!!!, por lo tanto veamos cómo les grabamos los datos en cada uno de sus campos...
void __fastcall TMiFormulario::BotonGrabarClick(TObject *Sender) { char Nombre[30], Email[40]; if((BoxNombre->Text=="")||(BoxEmail->Text=="")) Application->MessageBox("Introduzca datos","Atencion",MB_OK); else { strcpy(Nombre,BoxNombre->Text.c_str()); strcpy(Email,BoxEmail->Text.c_str()); if(BuscarNombre(Nombre)==0) { AltaDeNuevoNodo(Nombre,Email); LlenarCombo(); BoxNombre->Clear(); BoxEmail->Clear(); BoxNombre->SetFocus(); } else { MensajePorBox=Application->MessageBox("Desea ingresarlo nuevamente","Dato existente",MB_OKCANCEL); if(MensajePorBox==IDOK) { strcpy(NodoActual->CampoNodoNombre,BoxNombre->Text.c_str()); strcpy(NodoActual->CampoNodoEmail,BoxEmail->Text.c_str()); BoxNombre->Clear(); BoxEmail->Clear(); BoxNombre->SetFocus(); } else { BoxNombre->Clear(); BoxEmail->Clear(); BoxNombre->SetFocus(); } } } } //---------------------------------------------------------------------------
Ahora ya tenemos nuestro trencito con los vagones cargados.. Oohh.!! perdón, tenemos la lista enlazada con sus nodos con datos en sus campos.
En los siguientes links, veremos las operaciones más comunes que podemos efectuar con estos nodos.
PARADIGMA HUMANO
En este link encontrarás la codificación de los algoritmos para visualizar los datos que cargaste en cada uno de los nodos de tu estructura dinámica.
//--------------------------------------------------------------------------- void __fastcall TMiFormulario::Consultas1Click(TObject *Sender) { MiFormulario->Caption="Consulta de datos"; if(PrimerNodo != NULL) { PanelCombo->Visible=true; Combo->Clear(); BotonGrabar->Visible=false; BotonLimpiar->Visible=false; BotonEliminar->Visible=false; BotonModificar->Visible=false; LlenarCombo(); } else Application->MessageBox("No hay datos para consultar","Lista Vacia",MB_OK); } //---------------------------------------------------------------------------
Te ofrezco un combo..!!
//--------------------------------------------------------------------------- void TMiFormulario::LlenarCombo() { Combo->Clear(); Combo->Items->Clear(); NodoActual=PrimerNodo; while(NodoActual != NULL) { Combo->Items->Add(NodoActual->CampoNodoNombre); NodoActual=NodoActual->SiguienteNodo; } } //--------------------------------------------------------------------------- void __fastcall TMiFormulario::BotonAceptarClick(TObject *Sender) { int LoHalle; char DatoBuscado[40]; AnsiString DatoDelCombo; LoHalle=0; NuevoNodo=PrimerNodo; DatoDelCombo=Combo->Items->Strings[Combo->ItemIndex]; strcpy(DatoBuscado,DatoDelCombo.c_str()); while(NuevoNodo!=NULL) { if(stricmp(NuevoNodo->CampoNodoNombre,DatoBuscado)==0) { LoHalle=1; if(NuevoNodo->FlagNodoBaja!=1) { Panel->Visible=true; PanelCombo->Visible=false; BoxNombre->Text=NuevoNodo->CampoNodoNombre; BoxEmail->Text=NuevoNodo->CampoNodoEmail; NodoActual=NuevoNodo; NuevoNodo=NULL; } } else NuevoNodo=NuevoNodo->SiguienteNodo; } if(LoHalle==0) { ShowMessage("La ficha que busca no ha sido ingresada"); PanelCombo->Visible=false; } } //--------------------------------------------------------------------------- void __fastcall TMiFormulario::Visualizar1Click(TObject *Sender) { Fila=1; if(PrimerNodo==NULL) { Application->MessageBox("No hay datos en la lista","Atencion...",MB_OK); } PanelVisualizar->Visible = true; if (PrimerNodo!=NULL) { Grilla->Cells[0][0]="Nombre"; Grilla->Cells[1][0]="Email"; NuevoNodo = PrimerNodo; while (NuevoNodo->SiguienteNodo!= NULL) { Grilla->Cells[0][Fila]=NuevoNodo->CampoNodoNombre; Grilla->Cells[1][Fila]=NuevoNodo->CampoNodoEmail; Fila=Fila+1; while ( Grilla->Cells[0][Fila+1]!="") { Grilla->Cells[0][Fila+1]=""; Grilla->Cells[1][Fila+1]=""; } NuevoNodo=NuevoNodo->SiguienteNodo; } Grilla->Cells[0][Fila]=NuevoNodo->CampoNodoNombre; Grilla->Cells[1][Fila]=NuevoNodo->CampoNodoEmail; } else { PanelVisualizar->Visible = false; } }
PARADIGMA HUMANO
Si nos equivocamos.. no hay drama..!!, buscamos dónde está el error, lo borramos y a otra cosa.!!!
//--------------------------------------------------------------------------- int BuscarNombre(AnsiString UnNombre) { int HayDato=0; NodoActual=PrimerNodo; if (NodoActual!=NULL) while (NodoActual != NULL) { if ((UnNombre)==NodoActual->CampoNodoNombre) { HayDato=1; break; } NodoActual=NodoActual->SiguienteNodo; } return(HayDato); } void __fastcall TMiFormulario::Bajas1Click(TObject *Sender) { MiFormulario->Caption="Eliminacion de datos"; if(PrimerNodo != NULL) { PanelCombo->Visible=true; BotonGrabar->Visible=false; BotonLimpiar->Visible=false; BotonModificar->Visible=false; BotonEliminar->Visible=true; Simple1->Enabled=false; LlenarCombo(); FlagBaja=1; } else Application->MessageBox("No hay datos para eliminar","Lista vacia",MB_OK); } //---------------------------------------------------------------------------
//--------------------------------------------------------------------------- //BOTON PARA ELIMNAR LOS DATOS void __fastcall TMiFormulario::BotonEliminarClick(TObject *Sender) { if(PrimerNodo != NULL) { MensajePorBox=Application->MessageBox("Desea Eliminar estos datos","Eliminacion de datos",MB_OKCANCEL); if(MensajePorBox==IDOK) { FichaAuxiliar=NodoActual; if(NodoActual==PrimerNodo) PrimerNodo=NodoActual->SiguienteNodo; else { NodoActual=PrimerNodo; while(NodoActual->SiguienteNodo != NULL) { if(NodoActual->SiguienteNodo==FichaAuxiliar) { FichaTrucha,NodoActual; break; } NodoActual=NodoActual->SiguienteNodo; } FichaTrucha,FichaAuxiliar->SiguienteNodo; } delete(FichaAuxiliar); LlenarCombo(); Application->MessageBox("Los datos fueron eliminados","Eliminacion de datos",MB_OK); } } else Application->MessageBox("No hay datos a eliminar","La lista HayDato vacia",MB_OK); BoxNombre->Clear(); BoxEmail->Clear(); } //---------------------------------------------------------------------------
PARADIGMA HUMANO
Si deseas corregir el contenido de un nodo en particular, lo ubicas a este y luego activas el siguiente algoritmo
//--------------------------------------------------------------------------- void __fastcall TMiFormulario::BotonModificarClick(TObject *Sender) { strcpy(NodoActual->CampoNodoNombre,BoxNombre->Text.c_str()); strcpy(NodoActual->CampoNodoEmail,BoxEmail->Text.c_str()); Application->MessageBox("Los datos ya han sido modificados","Modificacion de datos",MB_OK); BoxNombre->Clear(); BoxEmail->Clear(); BoxNombre->SetFocus(); } //--------------------------------------------------------------------------- void __fastcall TMiFormulario::Modificaciones1Click(TObject *Sender) { MiFormulario->Caption="Modificacion de datos"; if(PrimerNodo != NULL) { PanelCombo->Visible=true; Combo->Clear(); BotonGrabar->Visible=false; BotonLimpiar->Visible=true; BotonModificar->Visible=true; BotonEliminar->Visible=false; Simple1->Enabled=false; LlenarCombo(); } else Application->MessageBox("No hay datos para modificar","Lista vacia",MB_OK); } //---------------------------------------------------------------------------
PARADIGMA HUMANO
A tu sistema le hará falta los siguientes accesorios...
void __fastcall TMiFormulario::BotonRegresarClick(TObject *Sender) { Panel->Visible=False; Simple1->Enabled=true; MiFormulario->Caption="Agenda de Wilo"; } //--------------------------------------------------------------------------- void __fastcall TMiFormulario::BotonVolverClick(TObject *Sender) { PanelVisualizar->Visible=false; } //--------------------------------------------------------------------------- void __fastcall TMiFormulario::Imprimir1Click(TObject *Sender) { int RespuestaDeBox; { RespuestaDeBox=Application->MessageBox("Tu impresora HayDato prendida?","Atencion",MB_OKCANCEL); if (RespuestaDeBox==IDOK) PrintDialog1->Execute(); } } //--------------------------------------------------------------------------- void __fastcall TMiFormulario::PorNombre1Click(TObject *Sender) { if(PrimerNodo != NULL) { Ordenar(ParametroOrdenar); } else Application->MessageBox("No hay datos para ordenar","Lista vacia",MB_OK); } void TMiFormulario::Ordenar(int ParametroOrdenar) { if(PrimerNodo!=NULL) { MiNodo *a,*b,*c; if (Application->MessageBox("Se Ordenarán los Elementos de la Lista","ORDENAR",MB_ICONEXCLAMATION+MB_OKCANCEL)==1) { a=PrimerNodo; while(a->SiguienteNodo!=NULL) { b=a->SiguienteNodo; while(b!=NULL) { if (strcmp(a->CampoNodoNombre,b->CampoNodoNombre)>0) { c=new(MiNodo); strcpy(c->CampoNodoNombre,a->CampoNodoNombre); strcpy(c->CampoNodoEmail,a->CampoNodoEmail); strcpy(a->CampoNodoNombre,b->CampoNodoNombre); strcpy(a->CampoNodoEmail,b->CampoNodoEmail); strcpy(b->CampoNodoNombre,c->CampoNodoNombre); strcpy(b->CampoNodoEmail,c->CampoNodoEmail); } b=b->SiguienteNodo; } a=a->SiguienteNodo; } } } else { Application->MessageBox("No Hay Datos","ORDENAR",MB_DEFBUTTON1+MB_ICONEXCLAMATION); } }
///////////////////////////////////////////////////////////////// // C++BUILDER 5 LISTA SIMPLE CON ARCHIV0 // ListaPrograma.cpp Wilucha 22/09/02 //--------------------------------------------------------------- // Al iniciar el programa se transfieren los datos grabados en un // archivo secuencial a los nodos de una lista. //--------------------------------------------------------------- // Las operaciones ABM y consultas solo se hacen sobre los nodos //--------------------------------------------------------------- // Al terminar el programa se transfieren los datos registrados en // los nodos de una lista a un archivo secuencial. //--------------------------------------------------------------- #include < vcl.h > #include < fstream.h > #include < stdlib.h > #pragma hdrstop #include "ListaPrograma.h" #pragma package(smart_init) #pragma resource "*.dfm" //----------------------------------------------------------------- TMiFormulario *MiFormulario; ////////////////////////////////////////////////////////// // DECLARACION DE LA ESTRUCTURA DEL NODO ////////////////////////////////////////////////////////// struct MiNodo { char CampoNodoNombre[30]; char CampoNodoEmail[40]; int FlagNodoBaja; struct MiNodo *PunteroDeNodo; } ////////////////////////////////////////////////////////// // DECLARACION DE VARIABLES GLOBALES ////////////////////////////////////////////////////////// *PrimerNodo,*NodoActual,*NuevoNodo,*UltimoNodo; MiNodo *FichaAuxiliar,FichaTrucha; int MensajePorBox,ParametroOrdenar,FlagBaja,FilaNro; int BuscarCodigo(AnsiString); ////////////////////////////////////////////////////////// // DECLARACION DE LA ESTRUCTURA DE LA FICHA ////////////////////////////////////////////////////////// struct UnaFicha { char CampoFichaNombre[30]; char CampoFichaEmail[40]; }; ////////////////////////////////////////////////////////// // DECLARACION DEL ARCHIVO A USAR ////////////////////////////////////////////////////////// FILE *Archivo; UnaFicha MiFicha; ////////////////////////////////////////////////////////// // DECLARACION DEL UNICO FORMULARIO CONTENEDOR ////////////////////////////////////////////////////////// __fastcall TMiFormulario::TMiFormulario(TComponent* Owner) : TForm(Owner) { } ////////////////////////////////////////////////////////// // OPERACION AL ACTIVARSE EL FORMULARIO ////////////////////////////////////////////////////////// void __fastcall TMiFormulario::FormActivate(TObject *Sender) { FlagBaja=0; }
////////////////////////////////////////////////////////// // FUNCION PARA CREAR NUEVO NODO: Tiene 2 parámetros ////////////////////////////////////////////////////////// void AltaDeNuevoNodo(char ParamNombre[30],char ParamEmail[40]) { NuevoNodo = new MiNodo[sizeof(MiNodo)]; strcpy(NuevoNodo->CampoNodoNombre,ParamNombre); strcpy(NuevoNodo->CampoNodoEmail,ParamEmail); NuevoNodo->FlagNodoBaja=0; NuevoNodo->PunteroDeNodo=NULL; UltimoNodo=NuevoNodo; if(PrimerNodo==NULL) PrimerNodo=NuevoNodo; else { NodoActual=PrimerNodo; while(NodoActual->PunteroDeNodo != NULL) NodoActual=NodoActual->PunteroDeNodo; NodoActual->PunteroDeNodo=NuevoNodo; } } ////////////////////////////////////////////////////////// // FUNCIÓN PARA BUSCAR UN DATO EN LA LISTA ////////////////////////////////////////////////////////// int BuscarNombre(AnsiString UnNombre) { int HayDato=0; NodoActual=PrimerNodo; if (NodoActual!=NULL) while (NodoActual != NULL) { if ((UnNombre)==NodoActual->CampoNodoNombre) { HayDato=1; break; } NodoActual=NodoActual->PunteroDeNodo; } return(HayDato); } ////////////////////////////////////////////////////////// // CARGAR DATOS EN CAMPOS DEL NODO ////////////////////////////////////////////////////////// void __fastcall TMiFormulario::GrabarDatosDeBoxesClick(TObject *Sender) { char Nombre[30], Email[40]; if((BoxNombre->Text=="")||(BoxEmail->Text=="")) Application->MessageBox("Digita los datos","Atencion",MB_OK); else { strcpy(Nombre,BoxNombre->Text.c_str()); strcpy(Email,BoxEmail->Text.c_str()); if(BuscarNombre(Nombre)==0) { AltaDeNuevoNodo(Nombre,Email); LlenarCombo(); BoxNombre->Clear(); BoxEmail->Clear(); BoxNombre->SetFocus(); } else { MensajePorBox=Application->MessageBox("Quieres volver a ingresarlo","OJITO: Dato existente..!!",MB_OKCANCEL); if(MensajePorBox==IDOK) { strcpy(NodoActual->CampoNodoNombre,BoxNombre->Text.c_str()); strcpy(NodoActual->CampoNodoEmail,BoxEmail->Text.c_str()); BoxNombre->Clear(); BoxEmail->Clear(); BoxNombre->SetFocus(); } else { BoxNombre->Clear(); BoxEmail->Clear(); BoxNombre->SetFocus(); } } } }
///////////////////////////////////////////////////////////////////// // ARCHIVOS SECUENCIALES ///////////////////////////////////////////////////////////////////// // Archivo = fopen("NombreDeArchivo","ModoDeUso") // Abro archivo secuencial "Simple.txt" en modo lectura "rb" //------------------------------------------------------------------ // fread(&MiFicha,sizeof(MiFicha),1,Archivo): Leo 1 ficha de Archivo //------------------------------------------------------------------ // fclose(Archivo) Cierra el archivo //////////////////////////////////////////////////////////////////// // CARGA de la LISTA con el ARCHIVO EXISTENTE: "Simple.txt" // Cada ficha se transfiere a cada nodo de la lista //////////////////////////////////////////////////////////////////// void __fastcall TMiFormulario::FormCreate(TObject *Sender) { Archivo = fopen("Simple.txt","rb"); while(!feof(Archivo)) { fread(&MiFicha,sizeof(MiFicha),1,Archivo); if(!feof(Archivo)) AltaDeNuevoNodo(MiFicha.CampoFichaNombre,MiFicha.CampoFichaEmail); } fclose(Archivo); } /////////////////////////////////////////////////////////////////////// // CARGA de los NODOS de la LISTA al ARCHIVO EXISTENTE: "Simple.txt" // Cada Nodo se transfiere a cada Ficha del archino // fwrite(&MiFicha, sizeof(MiFicha),1,Archivo): Grabo una ficha //////////////////////////////////////////////////////////////////// void __fastcall TMiFormulario::Salir1Click(TObject *Sender) { MiNodo *NodoAuxiliar; NodoAuxiliar=PrimerNodo; if(Application->MessageBox("Deseas grabar las modificaciones en el archivo..", "ESTAS POR CERRAR EL PROGRAMA", MB_OKCANCEL+ MB_DEFBUTTON1|MB_ICONQUESTION)==IDOK) { Close(); Archivo=fopen("Simple.txt","wb"); while(NodoAuxiliar != NULL) { strcpy(MiFicha.CampoFichaNombre,NodoAuxiliar->CampoNodoNombre); strcpy(MiFicha.CampoFichaEmail,NodoAuxiliar->CampoNodoEmail); fwrite(&MiFicha, sizeof(MiFicha),1,Archivo); NodoAuxiliar=NodoAuxiliar->PunteroDeNodo; } fclose(Archivo); } } ////////////////////////////////////////////////////////// // ////////////////////////////////////////////////////////// void __fastcall TMiFormulario::Altas1Click(TObject *Sender) { MiFormulario->Caption="INGRESO DE DATOS"; PanelAltas->Visible=true; GrabarDatosDeBoxes->Visible=true; BotonLimpiar->Visible=true; BotonEliminar->Visible=false; BotonModificar->Visible=false; BoxNombre->Clear(); BoxEmail->Clear(); BoxNombre->SetFocus(); Simple1->Enabled=false; } ////////////////////////////////////////////////////////// // BOTON LIMPIAR DEL PANEL DE ALTAS ////////////////////////////////////////////////////////// void __fastcall TMiFormulario::BotonLimpiarClick(TObject *Sender) { BoxNombre->Clear(); BoxEmail->Clear(); BoxNombre->SetFocus(); } ////////////////////////////////////////////////////////// // CARGAR ComboNombre CON CAMPO DE NODO ////////////////////////////////////////////////////////// void TMiFormulario::LlenarCombo() { ComboNombre->Clear(); ComboNombre->Items->Clear(); NodoActual=PrimerNodo; while(NodoActual != NULL) { ComboNombre->Items->Add(NodoActual->CampoNodoNombre); NodoActual=NodoActual->PunteroDeNodo; } }
////////////////////////////////////////////////////////// // ORDENAR NODOS POR BURBUJA ////////////////////////////////////////////////////////// void TMiFormulario::Ordenar(int ParametroOrdenar) { if(PrimerNodo!=NULL) { MiNodo *a,*b,*c; if (Application->MessageBox("Se Ordenarán los Elementos de la Lista","ORDENAR",MB_ICONEXCLAMATION+MB_OKCANCEL)==1) { a=PrimerNodo; while(a->PunteroDeNodo!=NULL) { b=a->PunteroDeNodo; while(b!=NULL) { if (strcmp(a->CampoNodoNombre,b->CampoNodoNombre)>0) { c=new(MiNodo); strcpy(c->CampoNodoNombre,a->CampoNodoNombre); strcpy(c->CampoNodoEmail,a->CampoNodoEmail); strcpy(a->CampoNodoNombre,b->CampoNodoNombre); strcpy(a->CampoNodoEmail,b->CampoNodoEmail); strcpy(b->CampoNodoNombre,c->CampoNodoNombre); strcpy(b->CampoNodoEmail,c->CampoNodoEmail); } b=b->PunteroDeNodo; } a=a->PunteroDeNodo; } } } else { Application->MessageBox("No Hay Datos","ORDENAR",MB_DEFBUTTON1+MB_ICONEXCLAMATION); } } ////////////////////////////////////////////////////////// // ORDENAR POR NOMBRES ////////////////////////////////////////////////////////// void __fastcall TMiFormulario::PorNombre1Click(TObject *Sender) { if(PrimerNodo != NULL) { Ordenar(ParametroOrdenar); } else Application->MessageBox("No hay datos para ordenar","Lista vacia",MB_OK); } ////////////////////////////////////////////////////////// // MODIFICACIONES ////////////////////////////////////////////////////////// void __fastcall TMiFormulario::Modificaciones1Click(TObject *Sender) { MiFormulario->Caption="Modificacion de datos"; if(PrimerNodo != NULL) { PanelCombo->Visible=true; ComboNombre->Clear(); GrabarDatosDeBoxes->Visible=false; BotonLimpiar->Visible=true; BotonModificar->Visible=true; BotonEliminar->Visible=false; Simple1->Enabled=false; LlenarCombo(); } else Application->MessageBox("No hay datos para modificar","Lista vacia",MB_OK); } ////////////////////////////////////////////////////////// // BAJAS ////////////////////////////////////////////////////////// void __fastcall TMiFormulario::Bajas1Click(TObject *Sender) { MiFormulario->Caption="Eliminacion de datos"; if(PrimerNodo != NULL) { PanelCombo->Visible=true; GrabarDatosDeBoxes->Visible=false; BotonLimpiar->Visible=false; BotonModificar->Visible=false; BotonEliminar->Visible=true; Simple1->Enabled=false; LlenarCombo(); FlagBaja=1; } else Application->MessageBox("No hay datos para eliminar","Lista vacia",MB_OK); } ////////////////////////////////////////////////////////// // REGRESAR ////////////////////////////////////////////////////////// void __fastcall TMiFormulario::BotonRegresarClick(TObject *Sender) { PanelAltas->Visible=False; Simple1->Enabled=true; MiFormulario->Caption="Agenda de Wilo"; } ////////////////////////////////////////////////////////// // BAJA DE NODO ////////////////////////////////////////////////////////// void __fastcall TMiFormulario::BotonEliminarClick(TObject *Sender) { if(PrimerNodo != NULL) { MensajePorBox=Application->MessageBox("Desea Eliminar estos datos","Eliminacion de datos",MB_OKCANCEL); if(MensajePorBox==IDOK) { FichaAuxiliar=NodoActual; if(NodoActual==PrimerNodo) PrimerNodo=NodoActual->PunteroDeNodo; else { NodoActual=PrimerNodo; while(NodoActual->PunteroDeNodo != NULL) { if(NodoActual->PunteroDeNodo==FichaAuxiliar) { FichaTrucha,NodoActual; break; } NodoActual=NodoActual->PunteroDeNodo; } FichaTrucha,FichaAuxiliar->PunteroDeNodo; } delete(FichaAuxiliar); LlenarCombo(); Application->MessageBox("Los datos fueron eliminados","Eliminacion de datos",MB_OK); } } else Application->MessageBox("No hay datos a eliminar","La lista HayDato vacia",MB_OK); BoxNombre->Clear(); BoxEmail->Clear(); } ////////////////////////////////////////////////////////// // MODIFICACIONES ////////////////////////////////////////////////////////// void __fastcall TMiFormulario::BotonModificarClick(TObject *Sender) { strcpy(NodoActual->CampoNodoNombre,BoxNombre->Text.c_str()); strcpy(NodoActual->CampoNodoEmail,BoxEmail->Text.c_str()); Application->MessageBox("Los datos ya han sido modificados","Modificacion de datos",MB_OK); BoxNombre->Clear(); BoxEmail->Clear(); BoxNombre->SetFocus(); }
////////////////////////////////////////////////////////// // CONSULTAS ////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////// // BUSQUEDA POR COMBO ////////////////////////////////////////////////////////// void __fastcall TMiFormulario::AceptarDatoComboClick(TObject *Sender) { int LoHalle; char DatoBuscado[40]; AnsiString DatoDelCombo; LoHalle=0; NuevoNodo=PrimerNodo; DatoDelCombo=ComboNombre->Items->Strings[ComboNombre->ItemIndex]; strcpy(DatoBuscado,DatoDelCombo.c_str()); while(NuevoNodo!=NULL) { if(stricmp(NuevoNodo->CampoNodoNombre,DatoBuscado)==0) { LoHalle=1; if(NuevoNodo->FlagNodoBaja!=1) { PanelAltas->Visible=true; PanelCombo->Visible=false; BoxNombre->Text=NuevoNodo->CampoNodoNombre; BoxEmail->Text=NuevoNodo->CampoNodoEmail; NodoActual=NuevoNodo; NuevoNodo=NULL; } } else NuevoNodo=NuevoNodo->PunteroDeNodo; } if(LoHalle==0) { ShowMessage("La ficha que busca no ha sido ingresada"); PanelCombo->Visible=false; } } ////////////////////////////////////////////////////////// // VOLVER ////////////////////////////////////////////////////////// void __fastcall TMiFormulario::BotonVolverClick(TObject *Sender) { PanelGrilla->Visible=false; } ////////////////////////////////////////////////////////// // VISUALIZACION DEL COMBO ////////////////////////////////////////////////////////// void __fastcall TMiFormulario::BuscarOpcionClick(TObject *Sender) { MiFormulario->Caption="Consulta de datos"; if(PrimerNodo != NULL) { PanelCombo->Visible=true; ComboNombre->Clear(); GrabarDatosDeBoxes->Visible=false; BotonLimpiar->Visible=false; BotonEliminar->Visible=false; BotonModificar->Visible=false; LlenarCombo(); } else Application->MessageBox("No hay datos para consultar","Lista Vacia",MB_OK); } ////////////////////////////////////////////////////////// // VER DATOS POR GRILLA ////////////////////////////////////////////////////////// void __fastcall TMiFormulario::GrillaOpcionClick(TObject *Sender) { FilaNro=1; if(PrimerNodo==NULL) { Application->MessageBox("No hay datos en la lista","Atencion...",MB_OK); } PanelGrilla->Visible = true; if (PrimerNodo!=NULL) { MiGrilla->Cells[0][0]="Nombre"; MiGrilla->Cells[1][0]="Email"; NuevoNodo = PrimerNodo; while (NuevoNodo->PunteroDeNodo!= NULL) { MiGrilla->Cells[0][FilaNro]=NuevoNodo->CampoNodoNombre; MiGrilla->Cells[1][FilaNro]=NuevoNodo->CampoNodoEmail; FilaNro=FilaNro+1; while ( MiGrilla->Cells[0][FilaNro+1]!="") { MiGrilla->Cells[0][FilaNro+1]=""; MiGrilla->Cells[1][FilaNro+1]=""; } NuevoNodo=NuevoNodo->PunteroDeNodo; } MiGrilla->Cells[0][FilaNro]=NuevoNodo->CampoNodoNombre; MiGrilla->Cells[1][FilaNro]=NuevoNodo->CampoNodoEmail; } else { PanelGrilla->Visible = false; } }
//--------------------------------------------------------------------------- void __fastcall TMiFormulario::SalirOpcionClick(TObject *Sender) { MiNodo *NodoAuxiliar; NodoAuxiliar=PrimerNodo; if(Application->MessageBox("Deseas grabar las modificaciones en el archivo..", "ESTAS POR CERRAR EL PROGRAMA", MB_OKCANCEL+ MB_DEFBUTTON1|MB_ICONQUESTION)==IDOK) { Close(); Archivo=fopen("Simple.txt","wb"); while(NodoAuxiliar != NULL) { strcpy(MiFicha.CampoFichaNombre,NodoAuxiliar->CampoNodoNombre); strcpy(MiFicha.CampoFichaEmail,NodoAuxiliar->CampoNodoEmail); fwrite(&MiFicha, sizeof(MiFicha),1,Archivo); NodoAuxiliar=NodoAuxiliar->PunteroDeNodo; } fclose(Archivo); } } ////////////////////////////////////////////////////////// // IMPRIMIR ////////////////////////////////////////////////////////// void __fastcall TMiFormulario::ImprimeOpcionClick(TObject *Sender) { if (Application->MessageBox("OJITO: Tu impresora está prendida..??","Atencion",MB_OKCANCEL)==IDOK) PrintDialog1->Execute(); } //---------------------------------------------------------------------------