Afficher les accents dans la console

    Publicités

Users Who Are Viewing This Thread (Total: 0, Members: 0, Guests: 0)

arnaud39

Membre
Mar 21, 2012
92
0
311
43
Salut, j'ai rédigé sur le site du zero ce tuto mais il n'a pas été accepté :suspect:, donc je vous le donne là:

Afficher les accents et les caractères spéciaux dans la console


Le langage C++ est un des langages les plus célèbres au monde. Très utilisé, notamment dans le secteur des jeux vidéo qui apprécie ses performances et ses possibilités, le C++ est désormais incontournable pour les développeurs.

Le C++ est le descendant du langage C. Ces deux langages, bien que semblables au premier abord, sont néanmoins différents. Le C++ propose de nouvelles fonctionnalités, comme la programmation orientée objet (POO). Elles en font un langage très puissant qui permet de programmer avec une approche différente du langage C.

Mais ces deux langages sont-ils capables de corriger le problème d'accent du cmd?


Oui! Un grand oui même, car il existe plusieurs méthodes différentes.

Au cours de ce tutoriel nous allons voir différentes manières d'afficher les accents dans la console!

Il faut savoir avant tout que presque toutes les techniques montrées présentent certaines contraintes plus ou moins gênantes
Retour en haut
Sommaire du tutoriel :

Une technique simple et efficace!
CharToOemA
En créant une classe un peu spécial
Q.C.M.


Retour en haut
Une technique simple et efficace!

Savez vous que en C et C++ vous pouvez y programmer en Batch, le langage de la console de windows !

Hein ! Montre-nous comment tu fais !


Mais oui, je vais vous le montrer . Il suffit d'ecrire la commande:

Code : C++ - Sélectionner
1
system("instructionsEnBatch");


Pour vous donner une petite idée des commandes batch, tapez dans le cmd "help"
Code : Console - Sélectionner
Microsoft Windows XP [version 5.1.2600]
(C) Copyright 1985-2001 Microsoft Corp.

C:\Documents and Settings\NP>help
Pour plus d'informations sur une commande spécifique, entrez le nom de la comman
de HELP.
ASSOC Affiche ou modifie les applications associées aux extensions de
fichiers.
AT Planifie l'exécution de commandes ou programmes sur un ordinateur.
ATTRIB Affiche ou modifie les attributs d'un fichier.
BREAK Active ou désactive le contrôle étendu de CTRL+C.
CACLS Affiche ou modifie les listes de contrôles d'accès aux fichiers.
CALL Appelle un fichier de commandes depuis un autre fichier de commandes.
CD Modifie le répertoire ou affiche le répertoire en cours.
CHCP Modifie la page de code active ou affiche son numéro.
CHDIR Modifie le répertoire ou affiche le nom du répertoire en cours.
CHKDSK Vérifie un disque et affiche un relevé d'état.
CHKNTFS Affiche ou modifie la vérification du disque au démarrage.
CLS Efface l'écran.
CMD Lance une nouvelle instance de l'interpréteur de commandes de Windows.
COLOR Modifie les couleurs du premier plan et de l'arrière plan de la
console.
COMP Compare les contenus de deux fichiers ou groupes de fichiers.
COMPACT Modifie ou affiche la compression des fichiers sur une partition NTFS.
CONVERT Convertit des volumes FAT en volumes NTFS. Vous ne pouvez pas
convertir le lecteur en cours d'utilisation.
COPY Copie un ou plusieurs fichiers.
DATE Affiche ou modifie la date.
DEL Supprime un ou plusieurs fichiers.
DIR Affiche la liste des fichiers et des sous-répertoires d'un répertoire.
DISKCOMP Compare les contenus de deux disquettes.
DISKCOPY Copie le contenu d'une disquette sur une autre.
DOSKEY Modifie les lignes de commande, rappelle des commandes Windows, et
permet de créer des macros.
ECHO Affiche des messages à l'écran ou active/désactive l'affichage des
commandes.
ENDLOCAL Stoppe la localisation des modifications de l'environnement dans un
fichier de commandes.
ERASE Supprime un ou plusieurs fichiers.
EXIT Quitte l'interpréteur de commandes (CMD.EXE).
FC Compare deux fichiers ou groupes de fichiers, et affiche les
différences entre eux.
FIND Cherche une chaîne de caractères dans un ou plusieurs fichiers.
FINDSTR Cherche des chaînes de caractères dans un ou plusieurs fichiers.
FOR Exécute une commande sur chaque fichier d'un groupe de fichiers.
FORMAT Formate un disque pour utilisation avec Windows.
FTYPE Affiche ou modifie les types de fichiers utilisés dans les
associations d'extensions.
GOTO Poursuit l'exécution d'un fichier de commandes à une ligne identifiée
par une étiquette.
GRAFTABL Permet à Windows d'afficher un jeu de caractères en mode graphique.
HELP Affiche des informations sur les commandes de Windows.
IF Effectue un traitement conditionnel dans un fichier de commandes.
LABEL Crée, modifie ou supprime le nom de volume d'un disque.
MD Crée un répertoire.
MKDIR Crée un répertoire.
MODE Configure un périphérique du système.
MORE Affiche la sortie écran par écran.
MOVE Déplace un ou plusieurs fichiers d'un répertoire à un autre.
PATH Affiche ou définit le chemin de recherche des fichiers exécutables.
PAUSE Interrompt l'exécution d'un fichier de commandes et affiche un
message.
POPD Restaure la valeur précédente du répertoire courant enregistré par
PUSHD.
PRINT Imprime un fichier texte.
PROMPT Modifie l'invite de commande de Windows.
PUSHD Enregistre le répertoire courant puis le modifie.
RD Supprime un répertoire.
RECOVER Récupère l'information lisible d'un disque défectueux.
REM Insère un commentaire dans un fichier de commandes ou CONFIG.SYS.
REN Renomme un ou plusieurs fichiers.
RENAME Renomme un ou plusieurs fichiers.
REPLACE Remplace des fichiers.
RMDIR Supprime un répertoire.
SET Affiche, définit ou supprime des variables d'environnement Windows.
SETLOCAL Commence la localisation des changements de l'environnement dans un
fichier de commandes.
SHIFT Modifie la position des paramètres remplaçables dans un fichier de
commandes.
SORT Trie les éléments en entrée.
SUBST Affecte une lettre de lecteur à un chemin d'accès.
START Lance une fenêtre pour l'exécution du programme ou de la commande.
TIME Affiche ou définit l'heure de l'horloge interne du système.
TITLE Définit le titre de la fenêtre pour une session CMD.EXE.
TREE Représente graphiquement l'arborescence d'un lecteur ou d'un chemin.
TYPE Affiche le contenu d'un fichier texte.
VER Affiche le numéro de version de Windows.
VERIFY Indique à Windows s'il doit ou non vérifier que les fichiers sont
écrits correctement sur un disque donné.
VOL Affiche le nom et le numéro de série du volume.
XCOPY Copie des fichiers et des arborescences de répertoires.

C:\Documents and Settings\NP>


OK, je veux bien te croire mais on n'avance pas beaucoup là!


Du calme, nous allons voir cela tout de suite. Il y a une commande à connaître pour afficher du texte en batch:
Code : Autre - Sélectionner
1
echo CeQueTuVeux


Pour l'appliquer en C et C++ il va falloir ecrire:

#include <iostream>
using namespace std;

int main()
{
system("echo Salut, j'arrive à afficher les accents!");
return 0;
}


On compile et voilà ce que ça donne:

Code : Console - Sélectionner
Salut, mes élèves sont à la plage!
Appuyez sur une touche pour continuer...


Youpi, ça marche !

Si vous utilisez code:block, vous devrez rajouter la librairie <windows.h>


Super ton truc, mais on fait comment pour afficher ses variables avec echo?


Si vous vous êtes posé la question, bravo! Pour répondre a votre question, je vais devoir vous décevoir: ON NE PEUT PAS

Heureusement, il existe la parade un peu brouillone et qui va rajouter pas mal de ligne de code a notre programme! En fait, nous venons de découvrir la contrainte de cette méthode qui a tout de même un avantage: elle est simple!

Il faut alterner entre les

system("echo tonTruc"); et les cout << maVariable;

A cause de cette méthode, il faut passer plus de temps pour faire le même résultat sans accents.


Avant de passer a une autre méthode, j'aimerai vous montrer l’intérêt d'avoir inclue le langage batch dans le C et C++.

En effet, vous pouvez maintenant faire de nouvelle actions, en particulier agir sur l'ordinateur de la personne. Vous pouvez donc maintenant créer un raccourci d'internet explorer sur le bureau, ouvrir iTunes (grâce a la fonction start, qui permet aussi d'ouvrir une page web: start itunes.exe ou start google.fr (sans Ce lien n'est pas visible, veuillez vous connecter pour l'afficher. Je m'inscris!. Vous pouvez même déplacer des fichiers, et attention: des virus .

En batch, on peut créer des variables, cela peut donc régler le problème d'alternance entre cout <<maVariable et system("echo monTexte");, mais cela devient trop compliqué.
Retour en haut
CharToOemA

CharToOemA


Windows nous propose nativement une fonction qui permet d'afficher les accents dans la console. Malheureusement, elle n'est pas simple d'utilisation car il faut stocker ce que l'on veut écrire dans un tableau de char non statique, on a donc un très mauvais contrôle de la mémoire.

Malgré cela, je tiens tout de même a vous la montrer, cela vous donnera une idée précise sur la programmation.

Je vous dé-conseil fortement d'utiliser de l'utiliser, sauf si par le plus grand des hasards vous aviez déjà fait un programme contenant un tableau de char avec des accents dedans


Pour commencer, il faut inclure la libraire <Windows.h> car c'est lui qui propose cette fonction.

On a donc:
Code : C++ - Sélectionner
1
2
3
4
5
6
7
8
9
10
11
12
#include <iostream>
#include<Windows.h>

using namespace std;

int main()
{
char monTexte[80]; //Il faut une taille suffisante...

system("pause");
return 0;
}


Ensuite, nous allons convertir notre chaîne de caractère prête à être afficher dans la console.
Code : C++ - Sélectionner
1
CharToOemA("leTexte", maVariable);
puis demander a cout d'afficher la variable. Ce qui nous donne:

Code : C++ - Sélectionner
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <iostream>
#include<Windows.h>

using namespace std;

int main()
{
char bufCons[80]; //Il faut une taille suffisante...
CharToOemA("jérémy", bufCons);//On applique l'attribut spéciale a bufcons,
cout << bufCons; //et on affiche
system("pause");
return 0;
}


De la même manière que les exemples précédents, le but est d'écrire des chaines avec
des accents dans la console.

La fonction CharToOem convertit la chaîne prête à afficher dans la console.
Notez que j'utilise CharToOemA qui utilise la version ANSI, et non la version unicode.

La fonction OemToCharA fait l'inverse, et reconvertit comme c'était.

Les fonctions CharToOemBuffA et OemToCharBuffA font la même chose, mais on peut
spécifier la taille à convertir : elles pourront donc permettre de convertir
qu'une partie de la chaîne, ou bien sécuriser la conversion en donnant une
taille maximale.

Je tiens a remercier magma qui m'a expliqué comment faire.

Vous n’êtes pas obligés d'appeler votre tableau de char "bufcons"
Retour en haut
En créant une classe un peu spécial

Quésaquo?


Cela pourrait être un excellent exercice pour... les super-développeurs!

Je vais donc vous montrer le travail tout fait, on utilise donc la POO

Faites très attention, car
La méthode que je vais vous montrer est relativement complexe, essayez juste de lire cette sous-partie sans essayer de comprendre si vous n'y comprenez rien
Donc attention!


main.cpp:
Code : C++ - Sélectionner
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
#include <string>
#include <cstdlib>
#include "WinConsoleStreamBuf.h"

using namespace std;

int main()
{
cout << "Test : éàùçï" << endl; // Pas bon
{
loic::AccentsInMsWindowsConsoleHandler toto;
cout << "Test : éàùçï" << endl; // Bon
cout << "Bonjour à toi, quel est ton nom ? "; // Bon
string nom;
cin >> nom; // Bon
cout << "\nBonjour, " << nom << " !" << endl; // Bon
}
cout << "Test : éàùçï" << endl; // Pas bon
cin.ignore(); //Le programme ne se mélange pas les pinceaux!
}



WinConsoleStreamBuf.h:

Code : C++ - Sélectionner
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <streambuf>
#include <ostream>

#ifndef _WIN32
#error This file is only designed (and useful) on MsWindows
#endif

namespace loic
{

class WinConsoleStreamBuf: public std::streambuf
{
public:
explicit WinConsoleStreamBuf(std::streambuf *buf);
~WinConsoleStreamBuf();
std::streambuf *setUnderlyingBuffer(std::streambuf *newBuf);

private:
WinConsoleStreamBuf(WinConsoleStreamBuf &);
WinConsoleStreamBuf& operator=(WinConsoleStreamBuf&);
virtual std::streambuf* setbuf(char_type* s, std::streamsize n);

virtual int_type overflow(int_type c);
virtual int sync();
virtual int_type underflow();


std::streambuf *myBuf;
char myInputBuffer[2];
};

/**
* This class is aimed to be used following the RAII idiom
*/

struct AccentsInMsWindowsConsoleHandler
{
AccentsInMsWindowsConsoleHandler();
~AccentsInMsWindowsConsoleHandler();
};
} // namespace loic



Et WinConsoleStreamBuf.cpp:

Code : C++ - Sélectionner
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
#include "WinConsoleStreamBuf.h"
#include <iostream>
#include <ios>
#include <windows.h>

namespace loic
{

WinConsoleStreamBuf::WinConsoleStreamBuf(std::streambuf *buf):
myBuf(buf)
{
}

WinConsoleStreamBuf::~WinConsoleStreamBuf()
{
delete myBuf;
}

std::streambuf* WinConsoleStreamBuf::setbuf(char_type* s, std::streamsize n)
{
// ne fait rien, ce qui est autorisé. Une version plus complète
// devrait vraissemblablement utiliser setvbuf
return NULL;
}

WinConsoleStreamBuf::int_type WinConsoleStreamBuf::overflow(int_type c)
{
if (traits_type::eq_int_type(c, traits_type::eof()))
{
// la norme ne le demande pas exactement, mais si on nous passe eof
// la coutume est de faire la meme chose que sync()
return (sync() == 0
? traits_type::not_eof(c)
: traits_type::eof());
}
else
{
char charBuffer[2];
charBuffer[0] = static_cast<char>(c);
charBuffer[1] = 0;
char OEMBuffer[2];
CharToOem(charBuffer, OEMBuffer);
//std::cout << OEMBuffer;
myBuf->sputc(OEMBuffer[0]);
return true;
}
}

WinConsoleStreamBuf::int_type WinConsoleStreamBuf::underflow()
{
// Assurance contre des implementations pas strictement conformes à la
// norme qui guaranti que le test est vrai. Cette guarantie n'existait
// pas dans les IOStream classiques.
if (gptr() == NULL || gptr() >= egptr())
{
int gotted = myBuf->sbumpc();
if (gotted == EOF)
{
return traits_type::eof();
}
else
{
char OEMBuffer[2];
OEMBuffer[0] = static_cast<char>(gotted);
OEMBuffer[1] = 0;
OemToChar(OEMBuffer, myInputBuffer);
setg(myInputBuffer, myInputBuffer, myInputBuffer+1);
return traits_type::to_int_type(*myInputBuffer);
}
}
else
{
return traits_type::to_int_type(*myInputBuffer);
}
}


int WinConsoleStreamBuf::sync()
{
return myBuf->pubsync();
}

std::streambuf* WinConsoleStreamBuf::setUnderlyingBuffer(std::streambuf* newBuf)
{
std::swap(newBuf, myBuf);
return newBuf;
}


AccentsInMsWindowsConsoleHandler::AccentsInMsWindowsConsoleHandler()
{
std::cout.rdbuf(new WinConsoleStreamBuf(std::cout.rdbuf()));
std::cin.rdbuf(new WinConsoleStreamBuf(std::cin.rdbuf()));
}

namespace
{
void restoreDefaultBuffer(std::basic_ios<char> &s)
{
WinConsoleStreamBuf *oldBuf = dynamic_cast<WinConsoleStreamBuf*>(s.rdbuf());
if (oldBuf)
{
s.rdbuf(oldBuf->setUnderlyingBuffer(NULL));
delete oldBuf;
}
}
}

AccentsInMsWindowsConsoleHandler::~AccentsInMsWindowsConsoleHandler()
{
restoreDefaultBuffer(std::cout);
restoreDefaultBuffer(std::cin);
}

} // namespace loic


Ce code est assez complexe, mais une fois crée nous n'avons que du bonheur dans le main

Allez, cette fois-ci c'est vraiment la fin
Retour en haut
Q.C.M.

Que peut-on faire avec la fonction "system("");"?
On peut afficher des accents dans la console
On peut faire un gratin de pâtes
On peut faire appel au langage batch qui nous permet de pouvoir faire plus de choses.


Statistiques de réponses au QCM

Retour en hautMaintenant, vous savez afficher les accents dans la console . Cela a l'air de rien, mais tous les débutants en C ou C++ qui ne savent pas encore utiliser la SDL ou Qt peuvent pallier ce manque afin d'améliorer la présentation de leurs programmes.

Il est bon de noter que ce tutoriel n'est pas encore complet, d'autres sous-parties s'enchaînerons par la suite. N’hésitez pas à me faire part de vos commentaires!