Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: class_OpenGL en 5 Agosto 2016, 02:29 am



Título: [C++] Mini aporte, solución para la mayoría de problemas con la entrada de datos
Publicado por: class_OpenGL en 5 Agosto 2016, 02:29 am
Hola, muy buenas. Hoy quería poner una solución que quizás no se haya tenido en cuenta. Por ejemplo, es una solución para los problemas como: ¿por qué a veces cuando leo datos de la consola se salta alguna toma de datos? Bueno, la respuesta a eso es que probablemente al introducir datos en algún paso anterior, se han introducido datos de más y esos datos están esperando a salir, por lo que en la siguiente toma de datos, se toman datos del paso anterior.

Bueno, entonces, la solución que he descubierto (yo no la conocía) es usar el método std::istream::sync. Lo que hace este método es sincronizar el búfer interno en el que se almacenan esos datos de pasos anteriores con la toma de datos actual. Entonces, lo que habría que hacer es colocar ese método antes de cualquier toma de datos:

Código
  1. #include <iostream>
  2.  
  3. int main() {
  4. // Aquí llenaremos el búfer de datos innecesarios para demostrar el uso de std::cin.sync
  5. std::cout << "Introduzca datos: ";
  6. std::cin.get();
  7.  
  8. // ... Código
  9.  
  10. std::cout << "Introduzca datos de nuevo: ";
  11. std::cin.sync();
  12. // Pedimos un carácter y lo imprimimos:
  13. std::cout << (char)std::cin.get();
  14.  
  15. return 0;
  16. }

Este código tendría la siguiente salida (en este ejemplo):
Código:
Introduzca datos: aaaaaaaaaaaaaaaaa
Introduzca datos de nuevo: r
r

Como ven, a pesar de haber llenado el búfer con el carácter 'a', se ha impreso el último carácter leído. Eso demuestra que funciona. Lo que no me queda del todo claro es cómo funciona este método, así que quizás sea ineficiente o algo por el estilo.

Sabiendo esto, ¿alguien sabe si usar todo el rato std::istream::sync tiene algún inconveniente? Gracias!


Título: Re: [C++] Mini aporte, solución para la mayoría de problemas con la entrada de datos
Publicado por: ivancea96 en 5 Agosto 2016, 03:55 am
Preferible usar getline, o ignore.
El funcionamiento de sync depende del tipo de buffer, y de la implementación.
http://ideone.com/UMDA8w (http://ideone.com/UMDA8w)


Título: Re: [C++] Mini aporte, solución para la mayoría de problemas con la entrada de datos
Publicado por: class_OpenGL en 5 Agosto 2016, 08:27 am
Entonces, ¿qué es lo que hace exactamente este método? No lo entiendo muy bien


Título: Re: [C++] Mini aporte, solución para la mayoría de problemas con la entrada de datos
Publicado por: ivancea96 en 5 Agosto 2016, 13:37 pm
No tengo más que decir que lo que pone en esta wiki: http://en.cppreference.com/w/cpp/io/basic_streambuf/pubsync (http://en.cppreference.com/w/cpp/io/basic_streambuf/pubsync)
istream::sync termina llamando a streambuf::sync.
En general, explica que, en buffers de salida, escribe lo que tenga almacenado (como haría flush). En buffers de entrada, limpia lo almacenado y vuelve a leer.
Por defecto, no hará nada.

De istream: http://en.cppreference.com/w/cpp/io/basic_istream/sync (http://en.cppreference.com/w/cpp/io/basic_istream/sync)
Citar
sync() puede vaciar el buffer, rellenarlo, o no hacer nada. En Visual Studio, descartará la entrada que no haya sido tratada cuando se utilice con un flujo de entrada estándar.

En fin. Un método virtual genérico que, supongo, proveen para que manejes tus buffers.