]> git.llucax.com Git - z.facultad/75.42/string.git/commitdiff
Se corrige y prueba la entrada y salida de datos por streams.
authorLeandro Lucarella <llucax@gmail.com>
Sun, 28 Sep 2003 21:26:14 +0000 (21:26 +0000)
committerLeandro Lucarella <llucax@gmail.com>
Sun, 28 Sep 2003 21:26:14 +0000 (21:26 +0000)
ascii.cpp
ascii.h
unicode.cpp
unicode.h
universalstring.cpp
universalstring.h

index 9a0982ceed86c131af8f85e228c34660cfc188b7..1864fb8dd9de28af7fd9fcb6835f74c254a95d18 100644 (file)
--- a/ascii.cpp
+++ b/ascii.cpp
@@ -38,6 +38,14 @@ Ascii::~Ascii(void) {
 #endif
 }
 
 #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;
 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.
 }
 
 /// 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
 #ifdef DEBUG
     std::cerr << "En operator>> de Ascii." << std::endl;
 #endif
diff --git a/ascii.h b/ascii.h
index 86c0322dca12f24999e6a576a2e980b5346e156f..a2cb48c352143b890753cdfdf2edaef282ca53fe 100644 (file)
--- a/ascii.h
+++ b/ascii.h
@@ -41,6 +41,9 @@ class Ascii {
         /// Destructor.
         virtual ~Ascii(void);
 
         /// 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);
 
         /// 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::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);
 
 };
 
 
 };
 
index c0bfa8fafa372d379d590479e3894cf8ca33a307..127754b2b1fed3b0b92e9f5e48a60f98050377a8 100644 (file)
@@ -37,6 +37,15 @@ Unicode::~Unicode(void) {
     std::cerr << "En destructor de Unicode." << std::endl;
 #endif
 }
     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
 
 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
 #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
 #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;
 }
 
 }
 
index f232b675d0b42a3f9add7ee91f824eb7585465ef..1dcdc8741cfb524593c746c9d79ccf7adcba6109 100644 (file)
--- a/unicode.h
+++ b/unicode.h
@@ -28,7 +28,7 @@
 class Unicode {
 
         /// Caracter Unicode almacenado.
 class Unicode {
 
         /// Caracter Unicode almacenado.
-        char caracter;
+        short caracter;
 
     public:
 
 
     public:
 
@@ -41,6 +41,16 @@ class Unicode {
         /// Destructor.
         virtual ~Unicode(void);
 
         /// 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);
 
         /// 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);
 
         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,
         friend std::istream& operator>>(std::istream& in,
-                const Unicode& unicode);
+                Unicode& unicode);
 
 };
 
 
 };
 
index 57d458f34b4a2a2dceb3306cc6ddb2fb7ef270d1..5704ce63d7d2e09e637dbfa9a7e407c830e9bebe 100644 (file)
  * $Id$
  */
 
  * $Id$
  */
 
+#include <iostream>
 #include "ascii.h"
 #include "ascii.h"
+#include "unicode.h"
 #include "universalstring.h"
 #include <algorithm>
 #include "universalstring.h"
 #include <algorithm>
-#include <iostream>
+
+using namespace std;
 
 int main(void) {
 
 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;
 }
 
     return 0;
 }
 
index 6fac1ed7236a0cd21e5a490f8ddb0823438f06ba..4ec4d56b412f9b604e69182bc17c3944cc116d94 100644 (file)
@@ -105,6 +105,7 @@ class UniversalString {
 #ifdef DEBUG
             std::cerr << "En operator<< de UniversalString." << std::endl;
 #endif
 #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;
             std::copy(str.string.begin(), str.string.end(),
                     std::ostream_iterator<T>(out, ""));
             return out;
@@ -112,12 +113,20 @@ class UniversalString {
 
         /// Captura desde un stream de entrada.
         friend std::istream& operator>>(std::istream& in,
 
         /// 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
 #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;
         }
 
             return in;
         }