Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Sandoval U.
LECTURA Y ESCRITURA DE ARCHIVOS DE TEXTO.....................................................................................1 1.1 STREAMS ...............................................................................................................................................................1 1.1.1 Lectura de Archivos ......................................................................................................................................1 1.2 USING SYSTEM.IO .................................................................................................................................................2 1.3 CONTROL DE ERRORES ..........................................................................................................................................2 1.4 LECTURA: STREAMREADER ...................................................................................................................................2 1.4.1 Constructores de StreamReader....................................................................................................................2 1.4.2 Lectura con StreamReader............................................................................................................................3 1.4.3 Ejemplo: Lectura de un Archivo de Texto, mostrando contenido en pantalla ..............................................3 1.4.4 Ejemplo: Procesamiento de Operaciones Matemticas en Archivo .............................................................4 1.5 ESCRITURA: STREAMWRITER ................................................................................................................................6 1.5.1 Constructores de StreamWriter.....................................................................................................................6 1.5.2 Escritura con StreamWriter ..........................................................................................................................6 1.5.3 Ejemplo: Lectura y Escritura de un Archivo.................................................................................................7
BASES DE DATOS...................................................................................................................................................10 2.1 CONCEPTOS BSICOS DE BASES DE DATOS .........................................................................................................10 2.1.1 Base de Datos..............................................................................................................................................10 2.1.2 Sistema de Administracin de Base de Datos .............................................................................................10 2.1.3 Elementos relacionados a una Base de Datos.............................................................................................10 2.1.4 EJEMPLO .....................................................................................................................................................0 2.2 MODELOS DE BASES DE DATOS ...........................................................................................................................12 2.2.1 Esquema de Archivos ..................................................................................................................................12 2.2.2 Modelo Jerrquico ......................................................................................................................................12 2.2.3 Modelo Relacional ......................................................................................................................................13 2.2.4 Modelo Distribuido .....................................................................................................................................15 2.2.5 Modelo de BD Orientado a Objeto .............................................................................................................15 2.2.6 BD Multidimensional ..................................................................................................................................15 2.3 PROGRAMACIN DE BASES DE DATOS CON C# ....................................................................................................16 2.3.1 Ejemplo: Programa de Registro de Alumnos ..............................................................................................16
Rodrigo Sandoval U.
1.1
Streams
Un stream es como se denomina a un objeto utilizado para transferir datos. Estos datos pueden ser transferidos en dos posibles direcciones: Si los datos son transferidos desde una fuente externa al programa, entonces se habla de leer desde el stream. Si los datos son transferidos desde el programa a alguna fuente externa, entonces se habla de escribir al stream.
Frecuentemente, la fuente externa ser un archivo, pero eso no necesariamente es el caso, por lo que el concepto es utilizado ampliamente con fuentes de informacin externas de diversos tipos. Algunas otras posibilidades fuera de los archivos incluyen: Leer o escribir datos a una red utilizando algn protocolo de red, donde la intencin es que estos datos sean recibidos o enviados por otro computador. Lectura o escritura a un rea de memoria. La Consola La Impresora Otros ...
Algunas clases que C# provee para resolver este acceso a fuentes diversas incluyen las clases de tipo Reader y Writer.
Una observacin acerca de la declaracin de nombres/rutas de archivos en C#. Usualmente, la ruta de un archivo contiene el carcter \, que en C# se utiliza como caracter de control para smbolos especiales (como el cambio de lnea: \n). Sin embargo, entendiendo que no es el mismo sentido el que se le quiere dar en la interpretacin de rutas de archivos (por ej: C:\Mis documentos\Programas\ejemplo.cs), se utiliza una sintaxis particular, anteponiendo el smbolo @ antes del string con la ruta del archivo. Es decir: string rutaarchivo = @C:\Temp\archivo.txt;
IIC 1102
Pgina: 1
Rodrigo Sandoval U.
Esta declaracin evita la interpretacin de los dos caracteres \ como smbolos especiales y el string queda correctamente inicializado.
1.2
Using System.IO
Para el uso de estas clases, es necesario referenciar el uso del namespace System.IO, ya que System no contiene los elementos para el manejo de archivos. Por ello, los programas con acceso a archivos deben incluir la lnea: using System.IO;
1.3
Control de Errores
Si bien en una serie de instrucciones de ejecucin en lenguaje C# se pueden producir errores importantes, particularmente cuando hay input del usuario que debera tener cierta forma o valores, o en clculos matemticos (especficamente evitando divisiones por cero), es factible en C# tener cierto control sobre el comportamiento del programa ante dichas situaciones. Esencialmente, el bloque try-catch persigue precisamente tener cierto control sobre lo que el programa har en caso de producirse un error.
public int division(int n1, int n2) { int resultado = 0; try { resultado = n1/n2; } catch(Exception e) { Console.WriteLine("Error en la divisin de {0}/{1}\n\n{2}",n1, n2, e.ToString()); } }
1.4
Lectura: StreamReader
La ventaja de esta clase es que hace una operacin sobre archivos que resulta muy natural al momento de utilizarla.
IIC 1102
Pgina: 2
Rodrigo Sandoval U.
1.4.2.1
ReadLine()
Al igual que el conocido Console.ReadLine(), este mtodo lee una lnea completa de un archivo de texto hasta el cambio de lnea ms prximo. Al igual que su equivalente de consola, StreamReader.ReadLine() no incluye en el string el carcter de cambio de lnea. string linea = sr.ReadLine()
1.4.2.2
ReadToEnd()
Este mtodo, por su parte, se encarga de acumular la informacin que hay desde la lectura anterior (que pudo haberse hecho con ReadLine(), por ejemplo) hasta el final del archivo, todo en el mismo string. string linea = sr.ReadToEnd()
1.4.2.3
Read ()
Finalmente, el mtodo simple Read() se encarga de leer un caracter a la vez, lo que permite procesar smbolo por smbolo el contenido del archivo. Convenientemente, este mtodo reconoce el cambio de lnea y se lo salta como si no existiese. Cuando se encuentra con el fin de archivo, retorna un valor 1, considerando que su retorno es siempre un int (y no un char). int SigCaracter = sr.Read(); Este mismo mtodo ofrece una declaracin alternativa (sobrecarga), donde es posible leer una cantidad especfica de caracteres y almacenarlos en un arreglo de enteros. char[] CharArray = new char[100]; int[] nChars = sr.Read(CharArray, 0, 100); nChars es un arreglo con los enteros retornados por el mtodo, y ser menor si es que la cantidad de caracteres que quedan en el archivo es menor de 100.
class Archivo { StreamReader sr; bool abierto = false; // Constructor: Recibe el nombre del archivo y lo abre (con control errores) public Archivo(string filename) { try { sr = new StreamReader(filename); abierto = true; } catch(Exception e) { Console.WriteLine("Error en la apertura de \"{0}\": {1}", filename, e.ToString()); }
IIC 1102
Pgina: 3
Rodrigo Sandoval U.
} public void Mostrar() { string linea; if(!abierto) return; // Si no se pudo abrir, no hay nada que leer linea = sr.ReadLine(); while(linea != null) { // Lee lneas mientras haya (mientras sean !=null) Console.WriteLine(linea); linea = sr.ReadLine(); } sr.Close(); abierto = false; } } class MainApp { static void Main() { string nombre; Console.Write("Nombre del archivo: "); nombre = Console.ReadLine(); Archivo archivo = new Archivo(nombre); archivo.Mostrar(); Console.ReadLine(); } }
class Calculadora { StreamReader sr; bool abierto = false; // Constructor: Recibe el nombre del archivo y lo intenta abrir. // Si no puede abrirse para lectura, "abierto" queda como false public Calculadora(string filename) { try { sr = new StreamReader(filename); abierto = true; } catch(Exception e) { Console.WriteLine("Error en la apertura de \"{0}\": {1}", filename,e.ToString()); } }
IIC 1102
Pgina: 4
Rodrigo Sandoval U.
// Operacion: Recibe la operacin y dos nmeros en forma de string. // Retorna el resultado (int) de la operacin entre ambos nmeros. int Operacion(string op, string n1, string n2) { switch(op) { case "+": return( int.Parse(n1) + int.Parse(n2)); case "-": return( int.Parse(n1) - int.Parse(n2)); case "*": return( int.Parse(n1) * int.Parse(n2)); case "/": return( int.Parse(n1) / int.Parse(n2)); } return(0); }
// Procesar: lee lneas del archivo abierto, procesando el contenido en forma de operaciones. // Observaciones: al finalizar se cierra el stream. No se valida el formato de c/lnea.
public void Procesar() { string linea; string[] elementos; if(!abierto) return; // Si no se pudo abrir, no hay nada que leer linea = sr.ReadLine(); while(linea != null) { // Para poder usar Split(), las operaciones y los operandos deben // venir separados por espacios. elementos = linea.Split(); Console.WriteLine("{0} = {1}", linea, Operacion(elementos[1], elementos[0], elementos[2])); linea = sr.ReadLine(); } sr.Close(); abierto = false; } } class MainApp { static void Main() { string nombre; Console.Write("Nombre del archivo: "); nombre = Console.ReadLine(); Calculadora c = new Calculadora(nombre); c.Procesar(); Console.ReadLine(); } }
IIC 1102
Pgina: 5
Rodrigo Sandoval U.
1.5
Escritura: StreamWriter
Esta clase funciona prcticamente de la misma manera que StreamReader, excepto que su propsito es nicamente para escribir dentro de un archivo (u otro stream). Es relevante distinguir que en este caso, el proceso de apertura para escritura considera que: Si el archivo no existe lo crea vaco para comenzar a escribir. Si el archivo ya existe, lo deja vaco para comenzar a escribir. Si el archivo ya existe, es posible abrirlo en forma Append (agregar) para escribir al final.
1.5.2.1
WriteLine()
Totalmente equivalente a Console.WriteLine(), se utiliza la misma idea, y el mismo formato, sabiendo que se estar escribiendo el texto no a la consola, sino que al stream abierto con el constructor. string linea = Texto de prueba; sw.WriteLine(linea); sw.WriteLine(Los valores posibles son: {0} y {1}, 3, 5);
1.5.2.2
Write ()
Tambin presente, el mtodo simple Write(), permite escribir texto en el stream, de la misma forma que su equivalente mtodo de la clase Console. En este caso se reconocen las siguientes alternativas de uso: Imprimir un string string linea = Texto de prueba; sw.Write(linea);
IIC 1102
Pgina: 6
Rodrigo Sandoval U.
Imprimir un caracter char caracter = T; sw.Write(caracter); Imprimir un arreglo de caracteres char[] caracteres = new char[100]; for(int i=0; i<100; i++) caracteres[i] = +; sw.Write(caracteres); Imprimir una porcin de un arreglo de caracteres char[] caracteres = new char[100]; for(int i=0; i<100; i++) caracteres[i] = +; sw.Write(caracteres, 25, 50); // Desde posicin 25 se escriben 50 caracteres
IIC 1102
Pgina: 7
Rodrigo Sandoval U.
nombrearchivo2,e.ToString()); } } } // Operacion: Recibe la operacin y dos nmeros en forma de string. // Retorna el resultado (int) de la operacin entre ambos nmeros. int Operacion(string op, string n1, string n2) { switch(op) { case "+": return( int.Parse(n1) + int.Parse(n2)); case "-": return( int.Parse(n1) - int.Parse(n2)); case "*": return( int.Parse(n1) * int.Parse(n2)); case "/": return( int.Parse(n1) / int.Parse(n2)); } return(0); } // Procesar: lee el archivo abierto, lnea por lnea, // procesando el contenido en forma de operaciones y escribiendo // el resultado en un segundo archivo. // Observaciones: Al finalizar se cierran los dos streams. // No se valida el formato de c/lnea. public void Procesar() { string linea, linea2; string[] elementos; // Si no se pudo abrir, no se podr leer ni escribir if(!abierto1 || !abierto2) return; Console.WriteLine("Procesando ..."); linea = sr.ReadLine(); while(linea != null) { elementos = linea.Split(); // ahora graba los resultados en el segundo archivo linea2 = linea + " = " + Operacion(elementos[1], elementos[0], elementos[2]).ToString(); sw.WriteLine(linea2); linea = sr.ReadLine(); } sr.Close(); abierto1 = false; sw.Close(); abierto2 = false; Console.WriteLine("Listo"); } }
class MainApp { static void Main() { string nombre; Console.Write("Nombre del archivo: "); nombre = Console.ReadLine(); Calculadora c = new Calculadora(nombre); c.Procesar(); Console.ReadLine(); } }
IIC 1102
Pgina: 8
Rodrigo Sandoval U.
4 5 8 6
+ * /
4 6 2 3
= = = =
8 30 6 2
IIC 1102
Pgina: 9
Rodrigo Sandoval U.
2 Bases de Datos
Uno de los grandes objetivos de la computacin es la capacidad de procesar datos: muchos datos, en forma rpida, eficiente, y segura (confiable). Esto no era posible con mtodos manuales tradicionales. Hoy en da existen muchas aplicaciones computacionales, pero para este contexto se vuelven muy importantes aquellas que trabajan directamente con la administracin de datos.
2.1
Para la realidad computacional de nuestros das, es necesario definir dos elementos puntuales que existen en todo gran o pequeo sistema que maneje cantidades de datos: la Base de Datos (BD) y el Sistema Administrador de Base de Datos (DBMS).
IIC 1102
Pgina: 10
Rodrigo Sandoval U.
2.1.4 EJEMPLO
En una Compra-Venta de autos usados se manejan los datos de los vehculos existentes en el momento. Para poder utilizar informacin adecuada, se entiende que un auto es un objeto de tipo vehculo, y como tal posee ciertas caractersticas determinables: Marca y Modelo, Patente, Nmero de Puertas, Cilindraje, Color. Aplicando los conceptos mencionados de Bases de Datos: Campos Patente HK-2367 JG-2304 LM-3948 TF-3404 HK-2376 BC-2340 N Puertas 3 4 4 4 4 4 Cilindraje 1200 1800 1600 1800 1600 1600 Color Azul Blanco Rojo Gris Verde Rojo
Planilla de Datos o Tabla Marca y Modelo Suzuki Samurai Subaru Impreza Chevrolet Cavalier Toyota Corolla Toyota Corolla Chevrolet Cavalier
Registro
Llave Primaria La llave primaria se obtiene al seleccionar una combinacin de campos cuyos valores combinados no se repitan para ms de un registro. En este caso, podemos ver que el N de puertas es repetido, al igual que el color y el cilindraje. La marca y el modelo tambin se repiten, pero claramente ningn auto posee la misma patente de otro. Entonces la Patente es la candidata ideal para ser una llave Primaria.
Indice Puede ser relevante ordenar la lista de autos por orden alfabtico de la Marca+Modelo. Es decir, el ndice sera el que se ve a continuacin: Chevrolet Cavalier Chevrolet Cavalier Subaru Impreza Suzuki Samurai Toyota Corolla Toyota Corolla BC-2340 LM-3948 JG-2304 HK-2367 HK-2376 TF-3404
IIC 1102
Pgina: 0
Rodrigo Sandoval U.
Vista Como visin parcial de los datos se puede definir verbalmente algo como Todos aquellos autos, identificados por modelo, patente, y cilindraje, cuyo cilindraje sea mayor o igual a 1.700. Marca y Modelo Subaru Impreza Toyota Corolla Patente JG-2304 TF-3404 Cilindraje 1800 1600
2.2
Dados los conceptos bsicos de una BD, a travs del tiempo, ya para diversas necesidades se han diseado algunos esquemas o modelos que difieren en su estructura, lo cual muchas veces trae ventajas y desventajas. Muchos de los modelos diseados han quedado obsoletos frente a otros que cumplen de mejor manera con las exigencias funcionales. Algunas de las caractersticas que deben tener: Consistencia en los datos (todos los datos dicen lo mismo, no hay contradicciones) Orden (permite saber qu existe y qu no existe, y dnde) Rapidez en la bsqueda (necesidad de la realidad informtica de hoy) Integridad de los datos (que su solidez se garantice evitando perder datos valiosos con operaciones indirectas). Acceso compartido a los datos (de modo que distintas entidades (usuarios, aplicaciones, etc.) puedan acceder simultneamente a los datos.
IIC 1102
Pgina: 12
Rodrigo Sandoval U.
Este modelo muestra una realidad de una universidad, donde se dictan cursos de distinto tipo que tienen prerrequisitos, profesor (o profesores) que dicta(n) el curso, y alumnos que lo toman. Se distinguen algunos elementos como N Alumno como identificador de alumno. Un ejemplo puntual de este modelo podra darse con los siguientes datos:
AN-2 1
Computacin II
1 9:00
N7
23
Prez
1023 1293
Alvarez Ba rrios
98 7
Cabrera
El primer sistema que existi con esta esquema fue el IMS (Information Managment System) desarrollado en 1960. Este fue el precursor que fue aprovechado en la NASA en la dcada de los 60, en particular en el proyecto Apollo. Luego apareci System 2000 desarrollado por Intel. Una de las grandes ventajas de este sistema fue la posibilidad de estructurar datos en una forma ms completa que el esquema de archivos simples. An as, se vi en aprietos al momento de representar situaciones donde la naturaleza de los datos implicaba una doble jerarqua, o al momento de consultar sobre datos particulares.
2.2.3.1
Tipos de Relaciones
Al identificar dos o ms entidades que estn vinculadas, se distingue una relacin. Esta puede tener distinta cardinalidad, lo que se refiere a las repeticiones que se encuentran del vnculo. Supongamos las entidades del ejemplo de cursos en una universidad: curso, profesor, alumno. Cada curso puede ser dictado por uno o ms profesores, asisten varios alumnos a ese curso, los cules, a su vez asisten a otros cursos.
IIC 1102
Pgina: 13
Rodrigo Sandoval U.
2.2.3.2
Relacin 1 a 1
Cuando dos entidades se relacionan en forma nica. Por ejemplo, si se diera como restriccin que cada curso es dictado por un solo profesor, entonces Profesor es 1 a 1 a Curso.
2.2.3.3
Relacin 1 a N
Cuando dos entidades se relacionan de modo que una se relaciona varias veces con la otra. Por ejemplo, cada curso debe dictarse en una nica sala (1), pero en una sala se dictan varios cursos (a distintas horas obviamente), entonces Curso es 1 a N a Sala.
2.2.3.4
Relacin N a N
Cuando dos entidades se relacionan en forma abierta, es decir muchos de un tipo se relacionan con muchos del otro. Por ejemplo, los alumnos toman varios cursos y a su vez cada curso integra a varios alumnos, entonces Alumno es N a N a Curso. Este modelo de BD se desarroll fuertemente en los 80 y sigue siendo hasta hoy muy utilizado en forma comercial y universal. Otro de los grandes aportes desde el punto de vista de la ciencia que se hizo con este modelo es el lgebra relacional, donde en una manera formal se pueden establecer las relaciones entre las distintas entidades y cules son las caractersticas de estas relaciones.
2.2.3.5
Formas Normales
Para asegurar consistencia de los datos, integridad, y evitar redundancia y otras anomalas que algunos esquemas de datos proveen, en el modelo relacional es posible disear un esquema de tablas y relaciones que para un caso puntual pueda asegurar de mejor manera esa integridad y consistencia.
Esta definicin se hace a travs de Formas Normales, las cules definen ciertas reglas que deben cumplir los registros de cada tabla para asegurar estas caractersticas. Existen las formas Normales: 1NF, 2NF, 3NF y BCNF. Cada una de estas establece ciertas caractersticas que permiten mejorar la consistencia de datos, y la integridad. Por ejemplo, en el ejemplo de los Cursos de la Universidad, es posible definir un esquema de datos que maneje todos los datos de una manera muy rudimentaria. De esa manera se tendra una tabla como la siguiente:
Ttulo C. II C. II C. II
Sala N7 N7 N7
Despus de aplicar ciertas reglas los datos podran guardarse en varias tablas. En el esquema rudimentario recin mostrado, se pueden producir los siguientes problemas: Redundancia: el curso, su profesor y la sala se repiten para cada alumno del curso.
IIC 1102
Pgina: 14
Rodrigo Sandoval U.
Inconsistencia: es posible que en el primer registro diga AN-21 con Prez como profesor, pero en el 2. Registro puede decir AN-21, con Snchez como profesor. No hay cmo saber cul es el correcto. Problemas de insercin. Si agrego un nuevo alumno debo repetir todos los datos. Problemas de eliminacin. Si elimino todos los registros de los alumnos (es decir, este curso no tuvo alumnos), entonces se pierde la informacin del profesor que haba sido designado.
En el esquema relacional adecuado, aplicando algn nivel de formas normales se pueden evitar todos estos problemas definiendo tablas separadas, usualmente distinguiendo entidades distintas, y relaciones ms complejas (N a N).
2.2.6 BD Multidimensional
Con el creciente desarrollo de las aplicaciones computacionales orientadas a dar informacin de alto nivel, es decir, informacin que ha pasado por varias etapas de proceso desde el detalle de los datos, se han desarrollados esquemas que son capaces de contestar complejas preguntas que requieren de valores a un alto nivel de agregacin de los datos originales. Cuando se habla de la gestin de una empresa, hoy en da se habla de obtener informacin desde los datos originales que permitan tomar decisiones de acuerdo al comportamiento del negocio reflejado por los datos analizados en diversas dimensiones.
En palabras ms simples, cuando se requieren analizar los datos de ventas de productos de una fbrica, tanto por lnea de producto, o distribucin geogrfica, o travs del tiempo, es necesario tener parte de los datos ya digeridos. Si se intenta hacer sumas de detalles de facturas emitidas para obtener la informacin, segn un esquema relacional, la respuesta demorar largo tiempo en llegar, dependiendo de la cantidad de datos existentes. Una BD multidimensional utiliza un esquema en que los datos han sido procesados (sumados, recalculados totales, etc.) hasta cierto nivel y se organizan de acuerdo a las dimensiones relevantes del negocio. Esto permite contestare con buena eficiencia complejas preguntas, como tendencias, etc., pero imposibilita poder analizar una factura en particular (datos a gran nivel de detalle).
IIC 1102
Pgina: 15
Rodrigo Sandoval U.
2.3
Si bien hoy existen numerosas tecnolgicas maduramente desarrolladas para administrar datos en Bases de Datos, incluyendo lenguajes de manejo especializados, como es el SQL, es factible hacer programas que incluyan el manejo simple de informacin en archivos de datos de formato definido y acotado. En la gran mayora de estos programas, se define lo que se conoce como una capa lgica, que se conforma de clases que representan los datos almacenados en las diferentes tablas (o archivos), de modo que el resto del programa slo conoce la forma lgica de estas clases, y desconoce el formato de las tablas o archivos.
En este caso particular, se requiere permitir las siguientes operaciones: Ingresar un nuevo alumno Ingresar un nuevo curso Inscribir un alumno en un curso, en un semestre particular Mostrar todos los cursos Mostrar todos los alumnos Mostrar todas las inscripciones realizadas Leer los datos de los archivos correspondientes Guardar los datos de los archivos correspondientes.
Conceptualizacin de la Solucin Para este programa se requiere implementar las entidades: Lista de Alumnos, Lista de Cursos, Inscripciones. Las clases necesarias para implementar estas entidades son las siguientes: Alumno y ListaAlumnos Curso y ListaCursos Inscripcin y ListaInscripciones
Clase Alumno: contiene los datos bsicos de cada alumno y propiedades que permiten acceder a ellos Clase ListaAlumnos: maneja un conjunto de alumnos, permitiendo cargar y guardar datos de y hacia un archivo de texto con un formato especfico y adecuado. Adicionalmente permite operaciones como: Agregar Alumnos, Mostrar los Alumnos registrados, Buscar un Alumno en particular.
IIC 1102
Pgina: 16
Rodrigo Sandoval U.
Las clases Curso, ListaCurso, Inscripcion, y ListaInscripciones ofrecen elementos equivalentes, cada una en su propio contexto de informacin a manejar. Adicionalmente, en la clase principal ofrece mtodos para la manipulacin general de los datos, como son: Men de opciones Creacin de un nuevo Alumno, preguntando sus datos Creacin de un nuevo Curso, preguntando sus datos Registro de una nueva inscripcin, preguntando y validando el curso y el alumno correspondiente.
Algoritmo Principal 1. Crear las instancias de las listas de datos Leer los archivos con datos
2. Repetir mientras la opcin seleccionada no sea Salir a. Mostrar Men de Opciones b. Preguntar opcin c. Si la opcin no es Salir i. Ejecutar Opcin 3. Grabar datos en archivos desde las listas
Limitaciones El programa no hace todas las validaciones de datos ingresados por el usuario, pero particularmente requiere lo siguiente: Las descripciones de cursos deben ser un nico string sin espacios entre medio. Los nombres y apellidos no pueden ser compuestos (o al menos, no separados por espacios) Slo se maneja un nmero limitado de alumnos, un nmero limitado de cursos, y un nmero limitado de inscripciones Si bien se valida la existencia de los archivos antes de leerlos, se muestra un mensaje en pantalla derivado del registro de error de la plataforma .NET.
//-----------------------------------------------------------------------//-----------------------------------------------------------------------// Clase Curso: representa un curso con sus atributos bsicos //-----------------------------------------------------------------------class Curso { string sigla, descripcion; int creditos;
IIC 1102
Pgina: 17
Rodrigo Sandoval U.
public Curso(string s, string d, int c) { sigla = s.ToUpper(); descripcion = d.ToUpper(); creditos = c; } public string Sigla { get { return(sigla); } } public string Descripcion { get { return(descripcion); } } public int Creditos { get { return(creditos); } } }
//-----------------------------------------------------------------------//-----------------------------------------------------------------------// Clase ListaCursos: representa un conjunto de cursos //-----------------------------------------------------------------------class ListaCursos { Curso[] cursos; // Almacena la lista de cursos int cantidad = 0; const int MAX = 20; // Limitacin: 20 cursos mx string archivo = "cursos.dat"; // -----------------------------------------------------------------// Constructor: dimensiona la lista de alumnos en MAX public ListaCursos() { cursos = new Curso[MAX]; } // Limitacin: 20 cursos mx // -----------------------------------------------------------------// Constructor: dimensiona la lista de cursos en MAX // y carga los datos de archivo identificado por su nombre public ListaCursos(string filename) { StreamReader fr; cursos = new Curso[MAX]; archivo = filename; try { fr = new StreamReader(archivo); } catch(Exception e) { //OJO: esta lnea indicar warning: no se usa e // No se pudo abrir: se crea StreamWriter sw = new StreamWriter(archivo); sw.Close(); return; } string linea; linea = fr.ReadLine(); while(linea != null) { string[] datos = linea.Split(); // Formato del archivo tiene: creditos sigla descripcin Agregar(datos[1].ToUpper(), datos[2].ToUpper(), int.Parse(datos[0])); linea = fr.ReadLine(); } fr.Close(); } // ---------------------------------------------------------------------------// Guardar(): guarda datos en estructura al archivo identificado por su nombre public bool Guardar() { StreamWriter fw; try { fw = new StreamWriter(archivo); } catch(Exception e) { Console.WriteLine("Error en la apertura de \"{0}\": {1}", archivo,e.ToString()); return (false); } for(int i=0; i<cantidad; i++) fw.WriteLine("{0} {1} {2}",
IIC 1102
Pgina: 18
Rodrigo Sandoval U.
cursos[i].Creditos, cursos[i].Sigla, cursos[i].Descripcion); fw.Close(); return (true); } // -----------------------------------------------------------------// Agregar(): agrega un curso dado a la lista // Parmetros: Curso c, el curso a agregar public void Agregar(Curso c) { if(cantidad<MAX) cursos[cantidad++] = c; } // -----------------------------------------------------------------// Agregar(): agrega un curso dados sus datos, a la lista // Parmetros: la sigla, la descripcin, y los crditos public void Agregar(string s, string d, int c) { if(cantidad<MAX) { cursos[cantidad++] = new Curso(s,d,c); } } // ------------------------------------------------------------------// Atributo Cantidad - slo lectura, no se puede modificar "por fuera" public int Cantidad { get { return(cantidad); } } // ------------------------------------------------------------------------------// Mostrar(): muestra los datos registrados al momento public void Mostrar() { Console.WriteLine("\nCURSOS:"); for(int i=0; i<cantidad; i++) Console.WriteLine("{0} {1} {2}", cursos[i].Creditos, cursos[i].Sigla, cursos[i].Descripcion); Console.WriteLine("----------------------------------------------------\n"); } // ------------------------------------------------------------------------------// Buscar(): Busca curso definido por sigla. Retorna la posicin, -1 si no est. public int Buscar(string sigla) { for(int i=0; i<cantidad; i++) if( cursos[i].Sigla == sigla.ToUpper() ) return(i); return(-1); // Si lleg aqu: no lo encontr } // -----------------------------------------------------------------------------// GetCurso(): Entrega curso ubicado en la posicin n del arreglo, con n de 0..N-1 public Curso GetCurso(int n) { return(cursos[n]); } }
//-----------------------------------------------------------------------//-----------------------------------------------------------------------// Clase Alumno: representa un alumno con sus atributos bsicos //-----------------------------------------------------------------------class Alumno { string nombre, apellido; string fechanac; int numero; public Alumno(int num, string n, string a, string f) { numero = num; nombre = n.ToUpper(); apellido = a.ToUpper(); fechanac = f; } public string Nombre { get { return(nombre); } } public string Apellido { get { return(apellido); } }
IIC 1102
Pgina: 19
Rodrigo Sandoval U.
public string FechaNac { get { return(fechanac); } } public int Numero { get { return(numero); } } }
//-----------------------------------------------------------------------//-----------------------------------------------------------------------// Clase ListaAlumnos: representa un conjunto de alumnos //-----------------------------------------------------------------------class ListaAlumnos { Alumno[] alumnos; // Almacena la lista de alumnos int cantidad = 0; const int MAX = 20; // Limitacin: 20 alumnos mx string archivo = "alumnos.dat"; // -----------------------------------------------------------------// Constructor: dimensiona la lista de alumnos en MAX public ListaAlumnos(){ alumnos = new Alumno[MAX]; } // Limitacin: 20 alumnos mx // -----------------------------------------------------------------// Constructor: dimensiona la lista de alumnos en MAX // y carga los datos de archivo identificado por su nombre public ListaAlumnos(string filename) { StreamReader fr; alumnos = new Alumno[MAX]; archivo = filename; try { fr = new StreamReader(archivo); } catch(Exception e) { //OJO: esta lnea indicar warning: no se usa e // No se pudo abrir: se crea StreamWriter sw = new StreamWriter(archivo); sw.Close(); return; } string linea; linea = fr.ReadLine(); while(linea != null) { string[] datos = linea.Split(); // Formato del archivo tiene: num fecha nombre apellido Agregar(int.Parse(datos[0]), datos[2], datos[3], datos[1]); linea = fr.ReadLine(); } fr.Close(); } // -------------------------------------------------------------------------------// Guardar(): guarda datos en la estructura al archivo identificado por su nombre public bool Guardar() { StreamWriter fw; try { fw = new StreamWriter(archivo); } catch(Exception e) { Console.WriteLine("Error en la apertura de \"{0}\": {1}", archivo,e.ToString()); return (false); } for(int i=0; i<cantidad; i++) fw.WriteLine("{0} {1} {2} {3}", alumnos[i].Numero, alumnos[i].FechaNac, alumnos[i].Nombre, alumnos[i].Apellido); fw.Close(); return (true);
IIC 1102
Pgina: 20
Rodrigo Sandoval U.
} // -----------------------------------------------------------------// Agregar(): agrega un alumno dado a la lista // Parmetros: Alumno a, el alumno a agregar public void Agregar(Alumno a) { if(cantidad<MAX) alumnos[cantidad++] = a; } // -----------------------------------------------------------------// Agregar(): agrega un alumno dados sus datos, a la lista // Parmetros: el nmero, nombre, apellido, y fecha nacimiento public void Agregar(int num, string n, string a, string f) { if(cantidad<MAX) { alumnos[cantidad++] = new Alumno(num,n,a,f); } } // ------------------------------------------------------------------// Atributo Cantidad - slo lectura, no se puede modificar "por fuera" public int Cantidad { get { return(cantidad); } } // ------------------------------------------------------------------------------// Mostrar(): muestra los datos registrados al momento public void Mostrar() { Console.WriteLine("\nALUMNOS:"); for(int i=0; i<cantidad; i++) Console.WriteLine("{0} {1} {2} {3}", alumnos[i].Numero, alumnos[i].FechaNac, alumnos[i].Nombre, alumnos[i].Apellido); Console.WriteLine("-----------------------------------------------------"); } // -----------------------------------------------------------------------// Buscar(): Busca alumno definido por su numero. Retorna posicin, -1 si no est. public int Buscar(int numero) { for(int i=0; i<cantidad; i++) if( alumnos[i].Numero == numero ) return(i); return(-1); // Si lleg aqu: no lo encontr } // ------------------------------------------------------------------------------// GetAlumno(): Entrega alumno ubicado en posicin n del arreglo, con n de 0..N-1 public Alumno GetAlumno(int n) { return(alumnos[n]); } }
//-----------------------------------------------------------------------//-----------------------------------------------------------------------// Clase Inscripcion: representa la relacin entre un alumno y un curso //-----------------------------------------------------------------------class Inscripcion { string sigla; int numero, semestre; public sigla } public public public } Inscripcion(string s, int n, int m) { = s.ToUpper(); numero = n; semestre = m; string Sigla { get { return(sigla); } } int Numero { get { return(numero); } } int Semestre { get { return(semestre); } }
IIC 1102
Pgina: 21
Rodrigo Sandoval U.
//-----------------------------------------------------------------------//-----------------------------------------------------------------------// Clase ListaInscripciones: representa un conjunto de inscripciones //-----------------------------------------------------------------------class ListaInscripciones { Inscripcion[] inscripciones; // Almacena la lista de inscripciones int cantidad = 0; const int MAX = 60; // Limitacin: 60 inscripciones mx string archivo = "inscripciones.dat"; // -----------------------------------------------------------------// Constructor: dimensiona la lista de inscripciones en MAX public ListaInscripciones() { inscripciones = new Inscripcion[MAX]; } // -----------------------------------------------------------------// Constructor: dimensiona la lista de inscripciones en MAX // y carga los datos de archivo identificado por su nombre public ListaInscripciones(string filename) { StreamReader fr; inscripciones = new Inscripcion[MAX]; archivo = filename; try { fr = new StreamReader(archivo); } catch(Exception e) { //OJO: esta lnea indicar warning: no se usa e // No se pudo abrir: se crea StreamWriter sw = new StreamWriter(archivo); sw.Close(); return; } string linea; linea = fr.ReadLine(); while(linea != null) { string[] datos = linea.Split(); // Formato del archivo tiene: sigla numero semestre Agregar(datos[0].ToUpper(), int.Parse(datos[1]), int.Parse(datos[2])); linea = fr.ReadLine(); } fr.Close(); } // ------------------------------------------------------------------------------// Guardar(): guarda datos en la estructura al archivo identificado por su nombre public bool Guardar() { StreamWriter fw; try { fw = new StreamWriter(archivo); } catch(Exception e) { Console.WriteLine("Error en la apertura de \"{0}\": {1}", archivo,e.ToString()); return (false); } for(int i=0; i<cantidad; i++) fw.WriteLine("{0} {1} {2}", inscripciones[i].Sigla, inscripciones[i].Numero, inscripciones[i].Semestre); fw.Close(); return (true); } // -----------------------------------------------------------------// Agregar(): agrega una inscripcin dada a la lista // Parmetros: Inscripcion i, el curso a agregar
IIC 1102
Pgina: 22
Rodrigo Sandoval U.
public void Agregar(Inscripcion i) { if(cantidad<MAX) inscripciones[cantidad++] = i; } // -----------------------------------------------------------------// Agregar(): agrega un curso dados sus datos, a la lista // Parmetros: la sigla, la descripcin, y los crditos public void Agregar(string s, int n, int m) { if(cantidad<MAX) { inscripciones[cantidad++] = new Inscripcion(s,n,m); } } // ------------------------------------------------------------------// Atributo Cantidad - slo lectura, no se puede modificar "por fuera" public int Cantidad { get { return(cantidad); } } // -----------------------------------------------------------------------------// Mostrar(): muestra los datos registrados al momento public void Mostrar(ListaAlumnos la, ListaCursos lc) { Console.WriteLine("\nINSCRIPCIONES:"); for(int i=0; i<cantidad; i++) { Alumno a; Curso c; a = la.GetAlumno(la.Buscar(inscripciones[i].Numero)); c = lc.GetCurso(lc.Buscar(inscripciones[i].Sigla)); Console.WriteLine("{0} ({1}) - {2} ({3} {4}) en {5}", c.Sigla, c.Descripcion, a.Numero, a.Nombre, a.Apellido, inscripciones[i].Semestre); } Console.WriteLine("----------------------------------------------------\n"); } }
//-----------------------------------------------------------------------//-----------------------------------------------------------------------// Clase MainApp: Bloque del Algoritmo Principal y mtodos auxiliares //-----------------------------------------------------------------------class MainApp { // ---------------------------------------------------// ValidarFecha(): valida una fecha en formato ddmmaaaa static bool ValidarFecha(string fecha) { string digitos = "0123456789"; if(fecha.Length!=8) return (false); for(int i=0; i<fecha.Length; i++) if(digitos.IndexOf(fecha[i])<0) return (false); if(int.Parse(fecha.Substring(0,2))>31) return (false); if(int.Parse(fecha.Substring(0,2))==0) return (false); if(int.Parse(fecha.Substring(2,2))>12) return (false); if(int.Parse(fecha.Substring(2,2))==0) return (false); return (true); } static Alumno NuevoAlumno() { string nombre, apellido, fechanac; int numero; Console.WriteLine("Datos del nuevo alumno"); Console.Write("Nombre: "); nombre = Console.ReadLine(); Console.Write("Apellido: "); apellido = Console.ReadLine();
IIC 1102
Pgina: 23
Rodrigo Sandoval U.
do { Console.Write("Fecha Nac (ddmmaaaa): "); fechanac = Console.ReadLine(); } while (!ValidarFecha(fechanac)); Console.Write("Numero: "); numero = int.Parse(Console.ReadLine()); return(new Alumno(numero, nombre, apellido, fechanac)); } static Curso NuevoCurso() { string sigla, descripcion; int creditos; Console.WriteLine("Datos del nuevo curso"); Console.Write("Sigla: "); sigla = Console.ReadLine(); Console.Write("Descripcin: "); descripcion = Console.ReadLine(); Console.Write("Crditos: "); creditos = int.Parse(Console.ReadLine()); return(new Curso(sigla, descripcion, creditos)); } // -------------------------------------------------------------------------// NuevaInscripcion(): Crea una nueva inscripcin relacionando un alumno existente // con un curso que tambin debe ser existente. // Observaciones: Se le pide al usuario slo el N del alumno y la sigla del curso, // validando que ambos existan. static Inscripcion NuevaInscripcion(ListaAlumnos la, ListaCursos lc) { string sigla; int numero, semestre; Alumno a; Curso c; // Muestra listas en pantalla para ayudar al usuario a indicar datos. la.Mostrar(); lc.Mostrar(); Console.WriteLine("Inscripcin de Curso:"); do { Console.Write("N Alumno: "); numero = int.Parse(Console.ReadLine()); } while( la.Buscar(numero)<0 ); do { Console.Write("Sigla Curso: "); sigla = Console.ReadLine(); } while( lc.Buscar(sigla)<0 ); Console.Write("Semestre: "); semestre = int.Parse(Console.ReadLine()); a = la.GetAlumno(la.Buscar(numero)); c = lc.GetCurso(lc.Buscar(sigla)); Console.WriteLine("El alumno {0} {1} se inscribi en el curso {2} ({3})", a.Nombre, a.Apellido, c.Sigla, c.Descripcion); return(new Inscripcion(sigla, numero, semestre)); }
static int Menu(string[] opciones) { int contador = 1, op = 0; foreach(string opcion in opciones) Console.WriteLine("{0}) {1}",contador++,opcion); Console.Write("Ingrese su opcin: "); do op = int.Parse(Console.ReadLine()); while (op<=0 && op>=contador); return(op); } static void Main() { string[] opciones = { "Agregar Alumno", "Agregar Curso",
IIC 1102
Pgina: 24
Rodrigo Sandoval U.
"Inscribir en Curso", "Mostrar Alumnos", "Mostrar Cursos", "Mostrar Inscripciones", "Salir" }; int opcion = 0; const string archivocursos = "cursos.dat"; const string archivoalumnos = "alumnos.dat"; const string archivoinscripciones = "inscripciones.dat"; ListaCursos lc = new ListaCursos(archivocursos); ListaAlumnos la = new ListaAlumnos(archivoalumnos); ListaInscripciones li = new ListaInscripciones(archivoinscripciones);
do { opcion = Menu(opciones); switch(opcion) { case 1: la.Agregar(NuevoAlumno()); break; case 2: lc.Agregar(NuevoCurso()); break; case 3: li.Agregar(NuevaInscripcion(la,lc));break; case 4: la.Mostrar(); break; case 5: lc.Mostrar(); break; case 6: li.Mostrar(la,lc); break; } } while(opcion!=7); lc.Guardar(); la.Guardar(); li.Guardar(); } }
Instrucciones de compilacin. Para compilar este ejemplo, se debe copiar el cdigo en un archivo .cs y compilarlo individualmente. En este proceso aparecern 3 warnings relacionados los bloques try-catch de los constructores de las listas definidas, en especfico, indicando que la variable e no es utilizada. Se puede modificar ese bloque para utilizarla como parte de un mensaje adecuado, pero no es necesario en estricto rigor. Instrucciones de ejecucin. Para ejecutar correctamente este ejemplo, los archivos alumnos.dat, cursos.dat, e inscripciones.dat deeben estar ubicados en la misma carpeta del ejecutable, o bien no existir, y sern creados en dicha ubicacin.
IIC 1102
Pgina: 25