Utilizar setlocale( ) para ingresar caracteres especiales con cin

Iniciado por snoopty, 8 Septiembre 2021, 10:36 AM

0 Miembros y 1 Visitante están viendo este tema.

snoopty

Hola a todos !
Acaso es posible lograr lo que describo en " ASUNTO " ... ? ; En todo caso, existe otra función que nos permita evitar escribir Código ASCII o ASCII extendido dentro de un IO scanf/printf ??
El siguiente Código no me funciona :

#include <iostream>
#include <clocale>

using namespace std;

int main()
{

setlocale(LC_ALL, "spanish");
char c;


cout<<"Ingrese la Letra ' EñE ' "<<endl;
cin>>c;
cout<<"Ingresaste la  "<<c<<endl;

return(0);
}

/* Gracias por leer el mensaje */

Eternal Idol

La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón

snoopty

Gracias. Pero no, tengo la PC en bucle con Pantalla Azul al arrancar.....( ¿ Dev-C++ Embarcadero; o cualquier .cpp y su .exe generado pudieron haber generado esta Imposibilidad de arranque ?? ) estoy desde Apps Cxx y Dcoder ( Android ) y no funciona.
Existe algo de esto para las Apps ( ? )
Saludos !

Serapis

Cita de: snoopty en  9 Septiembre 2021, 00:30 AM
Gracias. Pero no, tengo la PC en bucle con Pantalla Azul al arrancar.....( ¿ Dev-C++ Embarcadero; o cualquier .cpp y su .exe generado pudieron haber generado esta Imposibilidad de arranque ?? )
Mira qué error arroja el BSOD... ese texto que aparece como:
*** STOP: 0x000... (0x0..., 0x0..., 0x0..., 0x0...)
En google puedes buscarlo, y te señalará las más que probables causas (que te ayuden a repararlo), típicamente (en estos casos) es un fichero dañado que el S.O. precisa para arrancar, menos frecuente suele ser un cambio de configuración. Pero si el problema te apareció justo al hacer pruebas con tu código, va a ser lo primero...
En realidad es conveniente preguntar en los propios foros de Microsoft, pues la diversidad de detalles pueden escapar a la solución específica que a alguien le funcionó.

RayR

Siempre es un dolor de cabeza trabajar con localización, sobre todo en Windows. No está mal como lo estabas haciendo, pero debes asegurarte de que la consola use la misma codificación. Cuando usas "Spanish" o "es-ES" para el locale, en realidad es como si pusieras "Spanish_Spain.1252". O sea estás configurando el código de página ANSI 1252, pero, si no recuerdo mal, la consola usa una codificación OEM, por lo que eñes y acentos no van a salir bien. Necesitas cambiar también la consola:

Código (cpp) [Seleccionar]

setlocale(LC_ALL, "es-ES");
/* O bien
setlocale(LC_ALL, "Spanish_Spain");
o
setlocale(LC_ALL, "Spanish_Spain.1252");
*/

// Cambia la salida
SetConsoleOutputCP(1252);

// Y la entrada
SetConsoleCP(1252);


Sin embargo, aunque ahora mismo no tengo donde probarlo, estoy casi seguro de que la fuente que usaba por defecto la consola en Windows 7 no tenía eñes ni acentos para esa codificación, por lo que si quieres que funcione en esa versión o anteriores debes asegurarte de cambiarla.

Alternativamente, puedes poner el locale a OEM:
Código (cpp) [Seleccionar]

// O "Spanish_Mexico.850", "Spanish_Argentina.850", etc
setlocale(LC_ALL, "Spanish_Spain.850");
// Es buena idea asegurarse de que la consola esté igual
SetConsoleOutputCP(850);
SetConsoleCP(850);


esto me parece que no tiene el problema de las fuentes en versiones anteriores de Windows, pero es más recomendable la forma anterior.

Esto aplica para los valores que se muestran y leen en la consola, pero no significa que los caracteres especiales que escribas en tu código se muestren correctamente. Eso depende de la codificación que use el editor con el que lo escribes, por lo que es muy mala idea usar este tipo de caracteres en el código (si lo abres en otro editor, o en el mismo editor pero en otra máquina o sesión, te lo va a descomponer). Una forma más portable es usar sus valores numéricos:

Código (cpp) [Seleccionar]

//Para ANSI 1252
cout << "Ingrese la Letra 'E""\xF1""E'" << endl;
//Para OEM 850
cout << "Ingrese la Letra 'E""\xA4""E'" << endl;


hay formas mucho mejores de manejar la localización, pero también son más complicadas. Para cosas simples yo creo que con esto basta.

RayR

Cita de: snoopty en  9 Septiembre 2021, 00:30 AM
Gracias. Pero no, tengo la PC en bucle con Pantalla Azul al arrancar.....( ¿ Dev-C++ Embarcadero; o cualquier .cpp y su .exe generado pudieron haber generado esta Imposibilidad de arranque ?? ) estoy desde Apps Cxx y Dcoder ( Android ) y no funciona.
Existe algo de esto para las Apps ( ? )
Saludos !

No vi eso. Lo que te puse aplica sólo para Windows. No sé cómo sea la terminal de Android que uses, pero se usa UTF-8 igual que en Linux, por lo que quizás algo así te pudiera funcionar:


Código (cpp) [Seleccionar]
setlocale(LC_ALL, "es-ES.UTF-8")
wcin.imbue(locale("es-ES.UTF-8"));
wcout.imbue(locale("es-ES.UTF-8"));


Y usarías las funciones y tipos "wide" para manejar texto. En lugar de cout, cin, string y char, usarías wcout, wcin, wstring, wchar_t, etc. Pero yo nunca trabajo de esta manera en la terminal, así que no sé si te sirva.

Pensándolo mejor, aunque usar las funciones wide hace más explícito el hecho de que en Unicode los caracteres pueden ocupar varios bytes (lo cual pensé que te podría evitar errores), creo que al final podría ser más confuso, por lo que igual puedes aplicar el imbue a cin y cout y seguir usándolos sin tener que lidiar con wcout y demás. De cualquier forma, no deberás usar variables char simples sino arreglos char o directamente string, aún si únicamente quieres leer un solo caracter.

Eternal Idol

Cita de: snoopty en  9 Septiembre 2021, 00:30 AM
Gracias. Pero no, tengo la PC en bucle con Pantalla Azul al arrancar.....( ¿ Dev-C++ Embarcadero; o cualquier .cpp y su .exe generado pudieron haber generado esta Imposibilidad de arranque ?? )

Es muy poco probable pero sin analizar un volcado de memoria es imposible saber la razon de la excepcion no controlada en modo Kernel que lo genero. Fijate si podes entrar en modo a prueba de fallos para empezar, de no ser posible usa la consola de recuperacion, y trata de encontrar el volcado de memoria (es un archivo %SystemRoot%\MEMORY.DMP o un directorio %SystemRoot%\Minidump). Lo podes abrir con el WinDbg (Debugging Tools for Windows hoy en dia viene con el SDK de Windows).
La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón