#endif
}
+bool Ascii::is_endl(void) {
+#ifdef DEBUG
+ std::cerr << "En Ascii::is_endl()." << std::endl;
+#endif
+ // Si es 0xA = 10 = '\n' devuelve true.
+ return caracter == '\n';
+}
+
Ascii& Ascii::operator=(const Ascii& ascii) {
#ifdef DEBUG
std::cerr << "En operator= de Ascii." << std::endl;
}
/// Captura desde un stream de entrada.
-std::istream& operator>>(std::istream& in, const Ascii& ascii) {
+std::istream& operator>>(std::istream& in, Ascii& ascii) {
#ifdef DEBUG
std::cerr << "En operator>> de Ascii." << std::endl;
#endif
/// Destructor.
virtual ~Ascii(void);
+ /// Indica si el caracter es de fin de línea.
+ bool is_endl(void);
+
/// Asignación de una instancia a otra.
Ascii& operator=(const Ascii& ascii);
friend std::ostream& operator<<(std::ostream& out, const Ascii& ascii);
/// Captura desde un stream de entrada.
- friend std::istream& operator>>(std::istream& in, const Ascii& ascii);
+ friend std::istream& operator>>(std::istream& in, Ascii& ascii);
};
std::cerr << "En destructor de Unicode." << std::endl;
#endif
}
+#include <iostream>
+bool Unicode::is_endl(void) {
+#ifdef DEBUG
+ std::cerr << "En Unicode::is_endl()." << std::endl;
+#endif
+ // Si los últimos 8 bits son 0xA = 10 = '\n' devuelve true.
+ return (static_cast<char>(caracter) == '\n')
+ || (static_cast<char>(caracter >> 8) == '\n');
+}
Unicode& Unicode::operator=(const Unicode& unicode) {
#ifdef DEBUG
#ifdef DEBUG
std::cerr << "En operator<< de Unicode." << std::endl;
#endif
- return out << unicode.caracter;
+ // Imprime el caracter como 2 caracteres ASCII.
+ // Si el primer caracter (bits mas significativos) es cero, entonces no lo
+ // imprime (es ASCII "puro").
+ if (unicode.caracter >> 8) {
+ out << static_cast<char>(unicode.caracter >> 8);
+ }
+ return out << static_cast<char>(unicode.caracter);
}
-std::istream& operator>>(std::istream& in, const Unicode& unicode) {
+std::istream& operator>>(std::istream& in, Unicode& unicode) {
#ifdef DEBUG
std::cerr << "En operator>> de Unicode." << std::endl;
#endif
- return in >> unicode.caracter;
+ char c1;
+ char c2;
+ // Lee los 2 primeros caracteres que no sean espacio.
+ in >> c1 >> std::noskipws >> c2 >> std::skipws;
+ // Los asigno como un short cuyos bits mas significativos corresponden al
+ // caracter 1 y los menos significativos al caracter 2.
+ unicode.caracter = (static_cast<short>(c1) << 8) + c2;
+ return in;
}
class Unicode {
/// Caracter Unicode almacenado.
- char caracter;
+ short caracter;
public:
/// Destructor.
virtual ~Unicode(void);
+ /**
+ * Indica si el caracter es de fin de línea.
+ * En este caso se toma cualquier caracter cuyos 8 bits más o menos
+ * significatios sean 0xA ("\n"). Probablmente sólo funcione en unix, ya
+ * que para Mac el caracter de nueva línea es 0xD ("/r"). En DOS debería
+ * andar ya que el fin de línea se compone de 2 caracteres: 0xDA, por lo
+ * tanto termina en 0xA y debería ser considerado fin de línea.
+ */
+ bool is_endl(void);
+
/// Asignación de una instancia a otra.
Unicode& operator=(const Unicode& unicode);
friend std::ostream& operator<<(std::ostream& out,
const Unicode& unicode);
- /// Captura desde un stream de entrada.
+ /**
+ * Captura desde un stream de entrada.
+ * Toma de a 2 caracteres, suponiendo que la consola puede \e escribir
+ * caracteres unicode. El primer caracter se usa como bits de mayor peso
+ * y el segundo como de menor peso. Por ejemplo, si se ingresa \c a2 se
+ * guarda internamente como el número 24882 ya que
+ * <tt>a = 97 = 0x61</tt>, <tt>2 = 50 = 0x32</tt> por lo que el valor
+ * guardado internamente es igual a <tt>0x6132 = 24882</tt>.
+ */
friend std::istream& operator>>(std::istream& in,
- const Unicode& unicode);
+ Unicode& unicode);
};
* $Id$
*/
+#include <iostream>
#include "ascii.h"
+#include "unicode.h"
#include "universalstring.h"
#include <algorithm>
-#include <iostream>
+
+using namespace std;
int main(void) {
- UniversalString<Ascii> s("Hola mundo");
- std::cout << s << std::endl;
+
+ // Ascii.
+ UniversalString<Ascii> sa("Hola mundo");
+ cout << sa << endl;
+ cin >> sa;
+ cout << sa << endl;
+
+ // Unicode.
+ UniversalString<Unicode> su("Hola mundo");
+ cout << su << endl;
+ cin >> su;
+ cout << su << endl;
return 0;
}
#ifdef DEBUG
std::cerr << "En operator<< de UniversalString." << std::endl;
#endif
+ // Copio el vector de caracteres al stream de salida.
std::copy(str.string.begin(), str.string.end(),
std::ostream_iterator<T>(out, ""));
return out;
/// Captura desde un stream de entrada.
friend std::istream& operator>>(std::istream& in,
- const UniversalString<T>& str) {
+ UniversalString<T>& str) {
#ifdef DEBUG
std::cerr << "En operator>> de UniversalString." << std::endl;
#endif
- std::copy(std::istream_iterator<T>(in), std::istream_iterator<T>(),
- back_inserter(str.string));
+ // Limpio la cadena actual.
+ str.string.clear();
+ T c;
+ // Obtengo primer caracter, incluyendo espacios.
+ in >> std::noskipws >> c;
+ // Mientras que no sea el fin de línea, sigo leyendo caracteres.
+ while (!c.is_endl()) {
+ str.string.push_back(c);
+ in >> std::noskipws >> c;
+ }
return in;
}