Voici un exemple qui montre quatre méthodes différentes, dont seule la troisième (C conio
) et le quatrième (API Windows native) travail (mais seulement si stdin/stdout ne sont pas redirigés) . Notez que vous avez toujours besoin d'une police qui contient le caractère que vous voulez montrer (Lucida Console supporte au moins le grec et le cyrillique). Notez que tout ici est complètement non portable, il n'y a tout simplement aucun moyen portable d'entrer/sortir des chaînes Unicode sur le 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);
}
- Edit 1: J'ai ajouté une méthode basée sur
conio
.
- Edit 2: J'ai foiré autour avec
_O_U16TEXT
un peu comme décrit dans le blog de Michael Kaplan, mais apparemment seulement eu wgets
interpréter les données (8 bits) de ReadFile
en UTF-16. Je vais enquêter un peu plus loin pendant le week-end.
Unicode n'est pas assez précis. Utilisez-vous UTF- [8/16/32]? Voulez-vous utiliser la même représentation en interne et quand elle est sérialisée dans un fichier? Si vous voulez convertir des représentations voulez-vous le faire manuellement ou via les paramètres régionaux en utilisant la facette codecvt? –
Comme vous le souhaitez !!! Pas de fichier et rien d'autre cin, et cout ça tout! – Narek
Après avoir lu divers threads sur ce sujet, ma conclusion est qu'il est impossible de faire en C++. Supprimez 'cin',' cout' et tout le reste des normes C++ et C et utilisez les fonctions Windows simples 'ReadConsoleW' et' WriteConsoleW'. Les standards C et C++ sont juste cassés à cet égard. – Philipp