1 /* vim: set et ts=4 sw=4 fdm=indent tw=80 fdl=1 fdn=1 fo+=t:
3 * Taller de Programación (75.42).
6 * Ordena texto ASCII o Unicode.
8 * Copyleft 2003 - Leandro Lucarella <llucare@fi.uba.ar>
9 * Puede copiar, modificar y distribuir este programa bajo los términos de
10 * la licencia GPL (http://www.gnu.org/).
12 * Creado: lun sep 29 20:21:44 ART 2003
17 /** \mainpage Trabajo Práctico IV
20 También puede ver <a href="../latex/refman.pdf">este documento en formato
25 También puede ver este documento en formato HTML en html/index.html.
28 \section objetivo Objetivo.
29 Los temas a practicar son:
30 - Clases \e Templates.
31 - Funciones \e Templates.
32 - Sobrecarga de operadores.
35 \section desarrollo Desarrollo.
36 \subsection clases Clases a desarrollar.
37 El formato \e unicode utiliza dos bytes por cada caracter, en
38 cambio en el formato ASCII clásico es suficiente un sólo byte
39 para representar cada caracter. Se debe implementar una clase
40 llamada Ascii que encapsule un dato de tipo char (un byte) y
41 otra llamada Unicode que encapsule un dato de tipo short (dos
42 bytes). Por otra parte, se debe desarrollar una clase \e template
43 llamada UniversalString que almacenará un string de cualquier
46 \subsubsection clase_ascii Clase Ascii.
49 <th>Método / Operador</td>
54 <td>Constructores</td>
57 <td>operador \<\<</td>
58 <td>Volcado de su contenido a la salida estándar</td>
61 <td>operador \>\></td>
62 <td>Captura de datos por la entrada estándar</td>
66 <td>Asignación de una instancia a otra</td>
70 <td>Comparación por menor de dos instancias</td>
74 <td>Comparación por igual de dos instancias</td>
78 \subsubsection clase_unicode Clase Unicode.
81 <th>Método / Operador</td>
86 <td>Constructores</td>
89 <td>operador \<\<</td>
90 <td>Volcado de su contenido a la salida estándar</td>
93 <td>operador \>\></td>
94 <td>Captura de datos por la entrada estándar</td>
98 <td>Asignación de una instancia a otra</td>
102 <td>Comparación por menor de dos instancias</td>
106 <td>Comparación por igual de dos instancias</td>
110 Es importante destacar que se debe poder hacer una asignación
111 de un objeto Unicode a un objeto Ascii y viceversa.
113 \subsubsection clase_universalstring Clase UniversalString.
116 <th>Método / Operador</td>
120 <td>UniversalString</td>
121 <td>Constructores</td>
124 <td>operador \<\<</td>
125 <td>Volcado de su contenido a la salida estándar</td>
128 <td>operador \>\></td>
129 <td>Captura de datos por la entrada estándar</td>
133 <td>Asignación de una instancia a otra</td>
137 <td>Comparación por menor de dos instancias</td>
141 <td>Comparación por igual de dos instancias</td>
145 De ser necesario, se puede implementar otros métodos a
146 cualquiera de las tres clases.
148 \subsubsection funcion_template Función Template.
149 Implementar una función template que aplique un quicksort
150 de los elementos de un vector de la STL.
152 Ej. de declaración de la función template:
154 template <class X> void quicksort(std::vector<X>& vec);
157 \subsubsection aplicacion Aplicación.
158 Se debe desarrollar una aplicación que guarde en dos
159 vectores de manera distinta (Ascii y Unicode) las
160 palabras que ingrese el usuario y las ordene para
161 luego imprimirlas por pantalla. Para ello, utilizar
162 dos vectores de la STL, uno que contenga elementos de
163 tipo UniversalString\<Ascii\> y otro de tipo
164 UniversalString\<Unicode\>. Ordenar los vectores con la
165 función template quicksort. El menú de la aplicación debe
168 1. Ingresar Palabra al Vector Ascii.
169 2. Ingresar Palabra al Vector Unicode.
170 3. Copiar Palabra de Vector a Vector.
176 Si se elige la opcion 3, la aplicación debe preguntar por el
177 vector origen (desde que vector se copia la palabra) y el
178 numero de índice de la palabra a copiar; de esta manera,
179 copiara la palabra al final del otro vector (queda a
180 criterio del alumno el formato para preguntar al usuario por
181 esos dos datos: vector origen e índice). Cuando se listan
182 los vectores, con la opcion 5, junto a cada palabra se debe
183 mostrar el índice de la misma. Ante cualquier error detectado
184 el programa deberá avisar por pantalla a través del mensaje
187 \note La aplicación debe liberar TODA la memoria alocada antes de
191 \section resolucion Resolución.
192 \subsection res_ascii Clase Ascii.
193 Esta es la clase más simple. Un caracter es representado por un char por
194 lo que el comportamiento de esta clase es bastante obvio y predecible.
196 \subsection res_unicode Clase Unicode.
197 Esta clase es levemente más compleja que Ascii. Un caracter es
198 representado por un short (2 bytes en plataformas de 32 bits
199 generalmente) por lo que se necesita de una conversión para lo que es la
200 entrada de datos (ya que las consolas comunes solo pueden ingresar
201 caracteres Ascii). La conversión es muy simple, sólo se ponen los 8 bits
202 más significativos en cero y los menos significativos con el valor del
203 caracter Ascii ingresado (un simple cast se encarga de esto). La
204 conversión inversa (de Unicode a Ascii, o char) es similar. Si los
205 primeros 8 bits (más significativos) son cero, se imprimen los últimos 8
206 bits (menos significativos) como si fueran un char (de nuevo un cast se
207 encarga de ello). En caso contrario, se imprimen 2 char (ya que las
208 consolas comunes no pueden mostrar un caracter Unicode), primero el de
209 los bits más significativos y luego el de los bits restantes.
211 \subsection res_universalstring Clase Template UniversalString.
212 Esta es la clase más compleja. Además de ser la clase un \e Template,
213 hay un par de métodos que requieren otra caracterización (en general los
214 métodos para convertir de un tipo de string a otro, como el/los
215 constructor/es de \e copia,
216 UniversalString::UniversalString(const UniversalString<T2>&), y el
217 operador de asignación, UniversalString::operator=()).
218 Otro punto conflictivo es la entrada de datos. Para simplificarla se
219 hizo que se tome toda la frase entera (hasta el fin de línea) en vez de
220 una sola palabra, para lo cual se tubo que usar los modificadores de
221 streams skipws y noskipws.
222 El almacenamiento interno de caracteres se realizó a través de un vector
225 \subsection res_quicksort Función Template quicksort.
226 No hay mucho que comentar sobre quicksort(). Al estar todos los
227 operadores del UniversalString sobrecargados, hacer el quicksort fue
228 como hacer un quicksort para cualquier tipo de dato nativo del lenguaje.
230 \section requerimientos Requerimientos y modo de uso.
231 \subsection plataforma Plataforma y compilador.
232 Este trabajo práctico fue realizado y probado bajo la plataforma Debian
233 GNU/Linux sid. El compilador utilizado fue GNU GCC versión 3.3.1.
234 El ejecutable entregado corre bajo esta plataforma y su uso se
235 describe en la \ref uso "siguiente sección".
237 De todas formas, al estar programado sólo utilizando funciones ANSI
238 C/C++, debería poder compilarse bajo cualquier plataforma y compilador
239 que soporte este estándar.
241 \subsection uso Modo de uso.
242 El \ref ::main "programa" debe ser llamado desde un intérprete de
243 comandos. Para compilarlo basta con tener el programa \c make y
244 ejecutarlo. Eso genera el archivo \c tp4 que puede ser ejecutado de
246 \verbatim $ ./tp4 \endverbatim
248 \section conclusiones Conclusiones.
249 Los mayores problemas se presentaron en la clase UniversalString, en
250 particular en el operador para ingresar datos de un stream de entrada y en
251 la conversión entre strings de distinto tipo de caracteres. Para eso tuve
252 que crear el método UniversalString::to_vector() para poder obtener el
253 string de caracteres desconocido en un formato conocido.
254 Con respecto a la entrada estándar, también tuve problemas con el \e buffer,
255 ya que en algunas ocasiones se capturaban solo parte de la entrada del
256 usuario y a la hora de usar nuevamente el objeto cin, recibía los datos
257 anteriormente entrados, comportamiento que no era deseado. Por eso tuve que
258 usar en varios lugares el método istream::ignore().