From: Leandro Lucarella Date: Sun, 28 Sep 2003 21:26:14 +0000 (+0000) Subject: Se corrige y prueba la entrada y salida de datos por streams. X-Git-Tag: svn_import~7 X-Git-Url: https://git.llucax.com/z.facultad/75.42/string.git/commitdiff_plain/f3e36100ec2a1f73877100992cddfdc8dc13312b?ds=sidebyside Se corrige y prueba la entrada y salida de datos por streams. --- diff --git a/ascii.cpp b/ascii.cpp index 9a0982c..1864fb8 100644 --- a/ascii.cpp +++ b/ascii.cpp @@ -38,6 +38,14 @@ Ascii::~Ascii(void) { #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; @@ -83,7 +91,7 @@ std::ostream& operator<<(std::ostream& out, const Ascii& ascii) { } /// 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 diff --git a/ascii.h b/ascii.h index 86c0322..a2cb48c 100644 --- a/ascii.h +++ b/ascii.h @@ -41,6 +41,9 @@ class Ascii { /// 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); @@ -60,7 +63,7 @@ class 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); }; diff --git a/unicode.cpp b/unicode.cpp index c0bfa8f..127754b 100644 --- a/unicode.cpp +++ b/unicode.cpp @@ -37,6 +37,15 @@ Unicode::~Unicode(void) { std::cerr << "En destructor de Unicode." << std::endl; #endif } +#include +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(caracter) == '\n') + || (static_cast(caracter >> 8) == '\n'); +} Unicode& Unicode::operator=(const Unicode& unicode) { #ifdef DEBUG @@ -78,13 +87,26 @@ std::ostream& operator<<(std::ostream& out, const Unicode& unicode) { #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(unicode.caracter >> 8); + } + return out << static_cast(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(c1) << 8) + c2; + return in; } diff --git a/unicode.h b/unicode.h index f232b67..1dcdc87 100644 --- a/unicode.h +++ b/unicode.h @@ -28,7 +28,7 @@ class Unicode { /// Caracter Unicode almacenado. - char caracter; + short caracter; public: @@ -41,6 +41,16 @@ class Unicode { /// 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); @@ -60,9 +70,17 @@ class 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 + * a = 97 = 0x61, 2 = 50 = 0x32 por lo que el valor + * guardado internamente es igual a 0x6132 = 24882. + */ friend std::istream& operator>>(std::istream& in, - const Unicode& unicode); + Unicode& unicode); }; diff --git a/universalstring.cpp b/universalstring.cpp index 57d458f..5704ce6 100644 --- a/universalstring.cpp +++ b/universalstring.cpp @@ -14,14 +14,27 @@ * $Id$ */ +#include #include "ascii.h" +#include "unicode.h" #include "universalstring.h" #include -#include + +using namespace std; int main(void) { - UniversalString s("Hola mundo"); - std::cout << s << std::endl; + + // Ascii. + UniversalString sa("Hola mundo"); + cout << sa << endl; + cin >> sa; + cout << sa << endl; + + // Unicode. + UniversalString su("Hola mundo"); + cout << su << endl; + cin >> su; + cout << su << endl; return 0; } diff --git a/universalstring.h b/universalstring.h index 6fac1ed..4ec4d56 100644 --- a/universalstring.h +++ b/universalstring.h @@ -105,6 +105,7 @@ class UniversalString { #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(out, "")); return out; @@ -112,12 +113,20 @@ class UniversalString { /// Captura desde un stream de entrada. friend std::istream& operator>>(std::istream& in, - const UniversalString& str) { + UniversalString& str) { #ifdef DEBUG std::cerr << "En operator>> de UniversalString." << std::endl; #endif - std::copy(std::istream_iterator(in), std::istream_iterator(), - 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; }