Amigos de el hacker. con alegría les informo que encontré la solución. Una solución a media, pero solución al fin y al cabo.
No estaba mal en la dirección que iba solo tenia que cambiar el enfoque.
La duda de si se puede recuperar una entrada por teclado fallida, aun no la resuelvo. Pero en vez de preguntarme si se podía recuperar una entrada fallida, cambie el enfoque y me pregunte si es que se podía devolver al buffer una entrada valida. Asi que me enfoque en el proceso que hay detrás de un stream.
Me encontré que existe una clase streambuf para la manipulación del buffer, la cual es también base para la clase ios.
Siendo sincero, es poco lo que pude rescatar de de esta clase debido a que opera a bajo nivel, para lo cual no estoy preparado. A demás, no todos los compiladores llevan consigo las funciones de esta clase, por lo que una posible solución a mi problema (o el de cualquiera) usando los métodos de esta clase, es poco viable.
Aun así. encontré que esta clase tiene la función int sputbackc(char); que devuelve un caracter al buffer de entrada interno, lo que era compatible con mi cambio de enfoque.
La verdad ni siquiera supe como instanciarla
De esta forma seguí mas arriba en la clase ios, luego a la clase istream y llegue a notar que la solución estaba en un método del propio objeto cin.
El objeto cin tiene un método con el mismo nombre istream& putback(char); que también devuelve un caracter a la entrada de buffer interno. Yo supongo que en realidad hace uso del método int sputbackc(char) de la clase streambuf (es solo una suposicion).
Asi que la probe:
char letra;
cin.sputback('r');
cin>>letra;
cout<<"letra vale: "<<letra;
y que creen!! La salida fue
letra vale: r
Esa era!!
Ahora puedo reintegrar una entrada valida (el valor de una variable) al flujo de entrada.
Entre ensayo y error, los cuales van dejando conclusiones sin base teórica, mi código quedo así.
mi_pila pila;
float num;
char letra;
while(true){
cout<<"Ingrese un numero o 's' para salir ";cin>>letra;
if(letra=='s'){ cin.ignore(256,'\n');break;}
else{ cin.sputback(letra);
cin>>num;
cin.clear();
cin.ignore(256,'\n');
//ahora viene el detalle y porque es solo una solución a medias
if(num==0){cout<<" Ingreso invalido para salir o agregar num"<<endl;}
else{cout<<"Agregamos a la pila"<<endl; pila.agregar(num);}
};
Una breve explicación:
Para que esto resulte, es necesario pensar que toda entrada debe ser siempre caracteres ya sea string o char.
Probé con una variable tipo string y realmente se hace demasiado engorroso utilizar el método sputback(). No lo recomiendo!! Así que me quede con con un tipo char considerando que solo necesito un carácter para determinar que se hace dentro el bucle.
//Ingresamos un caracter o una cadena da igual. Ya que se someterá a evaluación solo el primer caracter ingresado. Si el usuario (tengo un hijo de 4 años) digita el teclado por error y la primera entrada fue una 's' lo peor que sucederá sera es que saldrá del bucle.
cout<<"Ingrese un numero o 's' para salir ";cin>>letra;
Como siempre la entrada que se almacena en una variable de tipo char sera valida (pueden haber excepciones pero las desconozco), evaluamos la variable.
if(letra=='s'){ cin.ignore(256,'\n');break;}
La linea anterior de código nos dice que si la variable letra contiene un valor igual a 's' ,o mejor dicho, letra es igual a 's', vacíe el buffer de entrada (en caso de que se haya ingresado mas de un caracter por error) y salga del bucle.
Pero sino, devolvemos el contenido de la variable letra al buffer de entrada de esta forma.
cin.sputback(letra);
pd: Como resulta, tiendo a pensar que el metodo sputback(char) devuelve al buffer de entrada un caracter al inicio de la cola.
Como ahora como el primer valor ingresado esta devuelta en el buffer (que puede considerarse como numero, letra o cualquier tipo de valor), si agregamos la linea
cin>>num;
la variable num tomara este valor automáticamente(sin volver a ingresar por teclado) como de tipo numérico, si es que lo es. Si no lo es, por alguna razón que aun desconozco, el valor de num sera 0 (cero) pero se activara una bandera de error por lo que es necesario agregar la linea
cin.clear();
para eliminar el estado de error. Esto es necesario ya que si no se hace, este estado no permitirá que se efectué una posterior asignacion de la entrada a num y el valor agregado a la cola del buffer quedara ahi en un bucle eterno.
luego limpiamos el buffer (de nuevo por si hay una cadena que se ingreso por error)
con la linea
cin.ignore(256,'\n');
que basicamente dice que se ignore toda entrada almacenada en el buffer hasta 256 caracteres o hasta encontrar un enter.
Y es en la linea que viene el detalle y es la razón de porque dije al comienzo que era una solución a medias.
¿Recuerdan que dije que por algún motivo si la entrada no era un valor numérico la variable num tomaba el valor de cero?
bueno, este valor de 0 tendrá que ser el criterio para indicar al usuario que la entrada no es valida, por lo que si alguien de ustedes quiere que su variable tome el valor de cero, realmente no sabrá si fue ingresada a propósito o fue un error de digitación. en mi caso no importa ya que los valores que si ingresen serán mayores a cero.
if(num==0){cout<<"No es un una entrada valida para salir o para ser asignado"<<endl;}
y si no es cero agregamos o asignamos, lo que se quiera hacer, en mi caso agrego a la pila.
else{cout<<"Ingreso valido como numero distinto de cero"<<endl; pila.agregar(num);
nuevamente agrego el codigo para que no esten subiendo a mirarlo
mi_pila pila;
float num;
char letra;
while(true){
cout<<"Ingrese un numero o 's' para salir ";cin>>letra;
if(letra=='s'){ cin.ignore(256,'\n');break;}
else{ cin.sputback(letra);
cin>>num;
cin.clear();
cin.ignore(256,'\n');
//ahora viene el detalle y porque es solo una solución a medias
if(num==0){cout<<" Ingreso invalido para salir o agregar num"<<endl;}
else{cout<<"Agregamos a la pila"<<endl; pila.agregar(num);}
};
Esto dio resultado para mi y es portable en la medida que la clase iostream siga siendo parte del estándar de c++
Bueno. Espero que también les sirva y si hay alguien que pueda mejorar esto se lo agradecería bastante.
Muchas gracias a quienes participaron. Fueron realmente de ayuda.