Facultad de Ciencias Exactas, Ingeniería y Agrimensura Departamento de Sistemas e Informática Escuela de Electrónica Informática II Práctica Nº 4 – Entrada / Salida Resumen: Esta práctica está destinada a mostrar y ejercitar el uso de los diferentes flujos de entrada y salida (input-output) disponibles en Java dentro del paquete java.io. Problema 1: Escriba un programa que se invoque desde la línea de comandos con un argumento. Dicho argumento deberá ser numérico y validado convenientemente. El programa deberá pedir el ingreso de tantas cadenas de texto (Strings) como indique el citado argumento y luego listar por pantalla las mismas. Problema 2: (*) Diseñar una “base de datos” de los empleados de una compañía y un sistema que permita ingresar los datos de la misma por teclado, visualizarlos por pantalla, obtener el valor de los datos miembros y setear los mismos, todo según los siguientes lineamientos: Crear un arreglo del tipo usado para representar a un empleado y llenarlo luego con los datos correspondientes a 10 empleados ingresados por teclado. Hacer un menú que tenga las siguientes opciones: a) Calcular el sueldo mínimo (del arreglo de empleados) y la cantidad de veces que ocurre dicho sueldo en el arreglo b) Dado un sueldo (que el usuario ingresará por teclado) retornar la primera ocurrencia del mismo en el arreglo (su índice) o en el caso de que ningún empleado del arreglo tenga un sueldo igual al ingresado, mostrar un -1 c) Calcular el sueldo promedio de los empleados, mostrar en pantalla este valor y los datos del empleado cuyo sueldo esté más cerca de este promedio d) Salir Problema 3: (*) Dada la siguiente clase abstracta: abstract class Figura{ abstract double area(); } a) Definir las clases Rectángulo, Círculo y Triángulo que extiendan Figura. Implementar en estas clases todos los métodos y variables necesarios para ello, siempre al nivel más alto posible de la jerarquía de clases. Es posible modificar la clase Figura, siempre que siga siendo abstracta. b) Las clases de esta jerarquía deben implementar la interface: interface Ordenable{ boolean menor(Ordenable obj); } tal que sea posible ordenar Rectángulos, Círculos y Triángulos por su área. c) Definir una clase Test que tenga un método main() que realice lo siguiente: Permita que el usuario cree una cantidad arbitraria de objetos círculos, triángulos y rectángulos, solicitando la entrada por teclado de los valores necesarios para crear estas instancias. Muestre un mensaje por pantalla indicando cuál es la figura (tipo y área) de menor área. Problema 4: Escriba un programa que busque en un archivo de texto, la primera ocurrencia de un carácter particular e imprima por pantalla el número de línea y posición dentro de la misma de dicha ocurrencia. El programa debe tomar dos argumentos de la línea de comando, el primero de ellos es el nombre del archivo de texto y el segundo de ellos es el carácter buscado. El programa deberá mostrar por pantalla un mensaje de error en caso que se introduzca un número incorrecto de argumentos por línea de comando o si el segundo argumento es un String de longitud mayor a un carácter. Problema 5: Similar al problema 4 pero buscando ahora una cadena e indicando la cantidad de veces que esta cadena aparece en el archivo y las posiciones de cada una de ellas. Problema 6: Dado el siguiente porgrama, analizarlo, correrlo y realizar un programa para leer el archivo que produjo. import java.io.*; class prome { public static void main(String args[]) throws IOException { InputStream in=System.in; DataInputStream inputStream=new DataInputStream(in); DataOutputStream miarchivo = new DataOutputStream (new FileOutputStream("promedio.txt")); double promedio = 0.0; int numero1, numero2, numero3; System.out.println("Enter the first number:"); numero1 = Integer.valueOf(inputStream.readLine().trim()).intValue(); System.out.println("Enter the second number:"); numero2 = Integer.valueOf(inputStream.readLine().trim()).intValue(); System.out.println("Enter the third number:"); numero3 = Integer.valueOf(inputStream.readLine().trim()).intValue(); miarchivo.writeUTF("El promedio de "); miarchivo.writeInt(numero1); miarchivo.writeUTF(", "); miarchivo.writeInt(numero2); miarchivo.writeUTF(" y "); miarchivo.writeInt(numero3); miarchivo.writeUTF(" es "); promedio = (numero1 + numero2 + numero3) / 3; miarchivo.writeDouble(promedio); miarchivo.close(); String line=inputStream.readLine(); } } Problema 7: Reescribir el programa anterior reemplazando los metodos obsoletos por actuales. ¿Porqué no deberían utilizarse estos métodos obsoletos? Problema 8: Se pretende crear una aplicación Java para procesar información acerca de una lista de libros. De cada libro interesa almacenar información acerca de su título y nombre del autor. a) Escriba una clase Libro que pueda ser usada para crear objetos que representen libros. La clase debe tener un constructor que tome dos argumentos de tipo String para inicializar el título y autor del libro. Debe escribir métodos de acceso y actualización para título y autor y un método toString para mostrar información sobre el libro. b) Escriba el código de una clase ListaLibros que use un array para almacenar una lista de objetos Libro. La clase debe tener un constructor que inicialice una lista de libros vacía, un método para añadir un nuevo objeto Libro a la lista y un método toString que produzca información de la lista (cada libro debe listarse en una línea separada). Puede suponer que el número máximo de libros es 100. c) Se requiere poder leer información sobre libros que se encuentra en un archivo texto. En tal archivo cada libro está representado por dos líneas de texto, la primera donde figura el título y la segunda donde figura el autor del mismo. La primera línea del archivo contiene un entero que representa el número de libros listados en el archivo, por ejemplo: 2 Lord of the Rings Tolkien, J R R Java in a Nutshell Flanagan, David Escriba en la clase ListaLibros un método cargarDe que tome como argumento un String que representa el nombre del archivo desde donde leerá datos de libros y los añadirá en ListaLibros. d) Escriba en la clase ListaLibros un métod grabarA. Este método debe tomar como argumento un String que será el nombre de un archivo donde escribirá todos los datos de los libros de ListaLibros. El archivo tendrá el formato indicado más arriba. Problema 9 Resolver el problema anterior haciendo que métodos grabarA y cargarDe trabajen ahora exclusivamente con las clases ObjectInputStream y ObjectOutputStream. Problema 10: Dadas las clases e interface a implementar suministradas, completarlas con lo MINIMO necesario a fin de darle funcionalidad, sin agregar ni cambiar propiedades (campos). Luego completar la clase "prueba" para leer el archivo "personas.dat" (que contiene 2 hombres y 2 mujeres como objetos), meter los datos en un arreglo y luego mostrar en pantalla nombre, peso real y estado según la OMS, de cada persona del arreglo. interface estado{ double peso_teorico(); double IMC(); String estado_segun_OMS(); } class persona { private String nombre; protected double estatura; protected double peso; persona(String nom, double altura, double p){ nombre=nom; estatura=altura; peso=p; } public double IMC(){return ... ;} public String nombre(){return nombre;} ... } class mujer{ private int cantidad_de_hijos; mujer(String nom, double alto, double peso, int hijos){ ... } ... } class hombre{ boolean corpulento; ... } class prueba { public static void main (String [] z)throws IOException, ClassNotFoundException { … } } Debe tenerse en cuenta que: a) El peso teórico se calcula como: Mujeres: 50 kg para los primeros 1.5 m de altura más 2.5 kg por cada 2.5 cm adicionales, mas 0.65 Kg por un hijo ó 1.3 Kg por 2 hijos o mas. Hombres: 53 kg para los primeros 1.5 m de altura más 3 kg para cada 2.5 cm adicionales, mas 10% si el hombre es corpulento. b) El Indice de Masa Corporal (IMC) se calcula dividiendo los kilogramos de peso por el cuadrado de la estatura en metros y da origen a la siguiente clasificación acorde a la OMS: < 18,5: Peso Bajo (Indica delgadez, desnutricion o algún problema de salud) hasta 24,9 (hombres) o 23,9 (mujeres). Peso normal (Está catalogado como saludable) hasta 29.9 hombres ó 28.9 mujeres: Sobrepeso (u Obesidad leve) hasta 40 hombres ó 37 mujeres: Obesidad grado 2. > 40 hombres ó > 37 mujeres: Obesidad severa o grado 3. Nota: Para grabar archivos como el que debe leer este programa puede hacer otro programa utilizando el siguiente código (incompleto): ObjectOutputStream salida= new ObjectOutputStream(new FileOutputStream("personas.dat")); arreglo[0]= new hombre("Javier",1.75,83.0,false); arreglo[1]= new mujer("Marisa",1.80,72.0,0); arreglo[2]= new hombre("Juan",1.70,92.0,false); arreglo[3]= new hombre("Pedro",1.95,110.0,true); for (int i=0;i<=3;i++) salida.writeObject(arreglo[i]); Problema 11: Escribir una clase que posea un método que muestre por pantalla los resultados de examinar un archivo que contiene objetos de diferentes clases, que cuente el número de objetos Integer que contiene el mismo y que ignore objetos de otras clases. Problema 12: En cada linea de un archivo de nombre “datos.txt” se encuentran los datos de una función evaluada en los puntos dados en forma de pares x;f(x). Por ejemplo: 0,25 ;12,0 0,45 ; 24,5 0,75 ; 30,0 1,05 ; 40,3 2,00 ; 55,0 3 ; 83,0 ... Leer el archivo y calcular el polinomio de interpolación de Lagrange evaluándolo en puntos ingresados por teclado. Solución del problema 2: import java.io.*; class empleado { private String nombre; private int leg; private int edad; private int seccion; private float sueldo; private static int nro=100; empleado(){leg=nro++;} empleado(String n,int e,int sec, float s) { this(); nombre = n; edad = e; seccion = sec; sueldo = s; } void setNombre(String n){nombre=n;} void setedad(int e){edad=e;} void setseccion(int d){seccion=d;} void setsalario(float s){sueldo=s;} String devnombre(){return nombre;} int devedad(){return edad;} int devseccion(){return seccion;} int devleg(){return leg;} float devsueldo(){return sueldo;} public String toString(){ String d="\n NRO.LEGAJO: " + leg + "\nNOMBRE: " + nombre + "\nEDAD: " + edad; d += "\nSECCION:" + seccion + "\nSUELDO: " + sueldo; return d; } } class prueba_empleado { static String scanf() { String line; DataInputStream in=new DataInputStream(System.in); try { line=in.readLine(); return line; } catch (Exception e){ return "error"; } } public static void main(String []args) { empleado e[]= new empleado [5]; for (int i=0; i<=4;i++){ System.out.println("\nIngrese nombre del empleado "); String nom=scanf(); System.out.println("\nIngrese edad del empleado "); String ed=scanf(); int edn=Integer.valueOf(ed).intValue(); System.out.println("\nIngrese sección en la que trabaja "); String se=scanf(); int nse=Integer.valueOf(se).intValue(); System.out.println("\nIngrese sueldo del empleado "); String su=scanf(); float sl=Float.valueOf(su).floatValue(); e[i]=new empleado(nom, edn, nse, sl); } int opcion=0; while (opcion!=4) { // IMPRIME MENU DE OPCIONES System.out.println("\n1.- SUELDO MINIMO"); System.out.println("\n2.- BUSCAR"); System.out.println("\n3.- SUELDO PROMEDIO"); System.out.println("\n4.- SALIR"); String op=scanf(); opcion =Integer.valueOf(op).intValue(); int i; switch (opcion) { case 4:break; case 1: //BUSCA EL SUELDO MINIMO float smin; smin= e[0].devsueldo(); for(i=0;i<=4;i++) { if (e[i].devsueldo()<smin) smin=e[i].devsueldo(); } // CUENTA LA CANTIDAD DE SUELDOS MINIMOS int cant=0; for(i=0;i<=4;i++) { if (e[i].devsueldo()==smin) cant++; } // MUESTRA RESULTADOS System.out.println("\nEl sueldo mínimo es:"+ smin); System.out.println (" y se repite " + cant + "veces"); String x=scanf(); break; case 2: System.out.println("\nIngrese sueldo a buscar"); String su=scanf(); float sue=Float.valueOf(su).floatValue(); for(i=0; i<=4 && e[i].devsueldo()!= sue;i++); if (i==5) System.out.println("-1"); else System.out.println (i); break; case 3: float promedio=0; for (i=0;i<=4;i++) promedio += e[i].devsueldo(); promedio/=5; float dif,menordif=e[0].devsueldo(); int imenor=0; for (i=1;i<=4;i++) { dif = Math.abs(e[i].devsueldo() - promedio); if (dif < menordif) { menordif = dif; imenor = i;} } System.out.println ("\nSueldo promedio: " + promedio); System.out.println ("\nEl empleado que difieremenos del promedio es: \n"); System.out.println(e[imenor]); // SE USA toString } // cierra el switch } //cierra el while } //cierra el main } // cierra la clase Solución del problema 3: import java.io.*; interface Ordenable{ boolean menor(Ordenable obj);//public por defecto } abstract class Figura implements Ordenable{ abstract double area(); public boolean menor(Ordenable obj){//las clases que extienden de Figura implementan Ordenable Figura o= (Figura) obj; if (this. area()< o.area()) return true; else return false; } public String toString(){ return "es un "+getClass().getName()+" y tiene un área igual a: "+area(); } } class Rectangulo extends Figura{ private double alto; private double ancho; public Rectangulo (double al, double an){ //super(); llamado implícitamente alto=al; ancho=an; } double area(){//ojo no declarar public return ancho* alto; } } class Circulo extends Figura{ private double radio; public Circulo (double r){ radio=r; } double area(){//ojo no declarar public return Math.PI* radio*radio; } } class Triangulo extends Figura{ private double base; private double altura; public Triangulo (double b, double a){ //super(), llamado implícitamente base=b; altura=a; } double area( ){//ojo no declarar public return (base*altura)/2; } } class Test{ static String scanf() { String line; DataInputStream in=new DataInputStream(System.in); try { line=in.readLine(); return line; } catch (Exception e){ return "error"; } } public static void main (String [ ] args){ //como trabajo con arrays debo definir alguna dimensión lo sufic. Grande Figura [ ] vector= new Figura[100]; System.out. println("¿Desea ingresar una nueva Figura (Y/N)?"); String respuesta=scanf(); char r=respuesta.charAt(0);//debería chequear que sólo pueda responder Y o N (o y/n) int i=0; while (r=='y' || r=='Y'){ double ancho, alto, radio, base, altura; System.out.println("1.-Pulse 1 si desea ingresar un rectángulo"); System.out.println("2.-Pulse 2 si desea ingresar un círculo"); System.out.println("3.-Pulse 3 si desea ingresar un triángulo"); int opcion; String op=scanf(); opcion =Integer.valueOf(op).intValue(); switch(opcion){ case 1: System.out.println("Ingrese valor ancho rectángulo:"); op=scanf(); ancho= Double.valueOf(op).doubleValue(); System.out.println("Ingrese valor alto rectángulo:"); op=scanf(); alto= Double.valueOf(op).doubleValue(); vector[i]=new Rectangulo(alto,ancho);//debería chequear que i<100 i++; //debería chequear que i<100 break; case 2: System.out.println("Ingrese valor radio:"); op=scanf(); radio= Double.valueOf(op).doubleValue(); vector[i]=new Circulo(radio);//debería chequear que i<100 i++; //debería chequear que i<100 break; case 3: System.out.println("Ingrese valor base:"); op=scanf(); base= Double.valueOf(op).doubleValue(); System.out.println("Ingrese valor altura:"); op=scanf(); altura= Double.valueOf(op).doubleValue(); vector[i]=new Triangulo(base, altura);//debería chequear que i<100 i++; //debería chequear que i<100 break; }//fin switch System.out. println("¿Desea ingresar una nueva Figura (Y/N)"); respuesta=scanf(); r=respuesta.charAt(0); } //fin while Figura temp; for (int k=1;k<i;k++){//no hace falta recorrer todo el vector if(vector[k].menor(vector[0])){ temp=vector[0]; vector[0]=vector[k]; vector[k]=temp; }//fin if }//fin for, muestro la figura (tipo y área) menor if(vector[0]!=null) System.out.println("La figura menor "+vector[0]); }//fin main }//fin class Test