Aquí es un ejemplo que muestra cuatro métodos diferentes, de los cuales sólo el tercero (C conio
) y el cuarto (API nativa de Windows) trabajo (pero sólo si la entrada estándar/salida estándar no son redirigidos) . Tenga en cuenta que todavía necesita una fuente que contenga el carácter que desea mostrar (la consola Lucida admite al menos caracteres griegos y cirílicos). Tenga en cuenta que aquí todo es completamente no portátil, simplemente no hay una forma portátil de entrada/salida de cadenas Unicode en el terminal.
#ifndef UNICODE
#define UNICODE
#endif
#ifndef _UNICODE
#define _UNICODE
#endif
#define STRICT
#define NOMINMAX
#define WIN32_LEAN_AND_MEAN
#include <iostream>
#include <string>
#include <cstdlib>
#include <cstdio>
#include <conio.h>
#include <windows.h>
void testIostream();
void testStdio();
void testConio();
void testWindows();
int wmain() {
testIostream();
testStdio();
testConio();
testWindows();
std::system("pause");
}
void testIostream() {
std::wstring first, second;
std::getline(std::wcin, first);
if (!std::wcin.good()) return;
std::getline(std::wcin, second);
if (!std::wcin.good()) return;
std::wcout << first << second << std::endl;
}
void testStdio() {
wchar_t buffer[0x1000];
if (!_getws_s(buffer)) return;
const std::wstring first = buffer;
if (!_getws_s(buffer)) return;
const std::wstring second = buffer;
const std::wstring result = first + second;
_putws(result.c_str());
}
void testConio() {
wchar_t buffer[0x1000];
std::size_t numRead = 0;
if (_cgetws_s(buffer, &numRead)) return;
const std::wstring first(buffer, numRead);
if (_cgetws_s(buffer, &numRead)) return;
const std::wstring second(buffer, numRead);
const std::wstring result = first + second + L'\n';
_cputws(result.c_str());
}
void testWindows() {
const HANDLE stdIn = GetStdHandle(STD_INPUT_HANDLE);
WCHAR buffer[0x1000];
DWORD numRead = 0;
if (!ReadConsoleW(stdIn, buffer, sizeof buffer, &numRead, NULL)) return;
const std::wstring first(buffer, numRead - 2);
if (!ReadConsoleW(stdIn, buffer, sizeof buffer, &numRead, NULL)) return;
const std::wstring second(buffer, numRead);
const std::wstring result = first + second;
const HANDLE stdOut = GetStdHandle(STD_OUTPUT_HANDLE);
DWORD numWritten = 0;
WriteConsoleW(stdOut, result.c_str(), result.size(), &numWritten, NULL);
}
- Editar 1: He añadido un método basado en
conio
.
- Editar 2: He ensuciado alrededor con
_O_U16TEXT
un poco como se describe en el blog de Michael Kaplan, pero que al parecer sólo tenía wgets
interpretar los datos (8 bits) de ReadFile
como UTF-16. Voy a investigar esto un poco más durante el fin de semana.
Unicode no es lo suficientemente exacto. ¿Estás usando UTF- [8/16/32]? ¿Desea usar la misma representación internamente y cuando se serializa en un archivo? Si desea convertir representaciones, ¿quiere hacerlo manualmente o mediante la configuración regional utilizando codecvt facet? –
Como quieras !!! ¡Sin archivo y nada más cin, y cout eso! – Narek
Después de leer varios hilos sobre este tema, mi conclusión es que es imposible hacerlo en C++. Suelte 'cin',' cout' y todo lo demás de los estándares C++ y C y use las funciones simples de Windows 'ReadConsoleW' y' WriteConsoleW'. Los estándares C y C++ simplemente se han roto a este respecto. – Philipp