Bonjour,
J’introduis un petit contexte à ma question : je crée un fichier nommé "monFichier.txt", encodé en utf-8, dans lequel j’écris le caractère 'Ä’. Il a la particularité d’être stocké sur 2 caractères en utf-8
Je crée le petit code suivant (je ne fais aucun test de sécurité genre vérifier que le fichier est bien ouvert etc. pour ne pas nuire à la lisibilité du post) :
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <locale.h>
#define TAILLE 100
int main()
{
char* encodage = setlocale(LC_ALL, "");
if (encodage != NULL) printf("encodage terminal : %s\n", encodage);
FILE* fichier = fopen("monFichier.txt", "r");
char chaine[TAILLE];
fgets(chaine, TAILLE, fichier);
printf( "\nstrlen(chaine) : %zu\n", strlen(chaine));
printf( "chaine : %s\n", chaine);
int k;
for (k = 0 ; k < strlen(chaine) ; k++)
printf("chaine[%d] : %u, %c\n", k, (unsigned char)chaine[k], chaine[k]);
fclose(fichier);
return 0;
}
Il me semble bien que la ligne char* encodage = setlocale(LC_ALL, "");
renvoie la localisation actuelle utilisée par le terminal si j’en crois cette phrase du cours du site "En fait, l’appel à setlocale() permet aux fonctions de traductions de connaître la table et l’encodage utilisés par notre système" (dans le chapitre sur les chaînes de caractères larges). Donc pour moi, cette ligne permet de signaler aux fonctions l’encodage du terminal de la sortie standard sur Windows ?
et voici le retour de mon code :
encodage terminal : French_France.1252
strlen(chaine) : 2
chaine : Ã"
chaine[0] : 195, Ã
chaine[1] : 132, "
En allant voir sur le net la table indiquée par l’encodage du terminal (French_France.1252) ce n’est pas cohérent ! Comme montré ci-dessus, le caractère 'Ä' est encodé en utf-8 par les octets 195 et 132, ce qui dans la table de French_France.1252 correspond à 'Ã' et '„' (et non pas '"’, la différence n’est pas esthétique, ce sont bien deux caractères différents).
Si maintenant on refait le test en changeant la localisation par char* encodage = setlocale(LC_ALL, "C");
pour remettre en anglais par défaut, on a ce retour :
encodage terminal : C
strlen(chaine) : 2
chaine : Ä
chaine[0] : 195, ├
chaine[1] : 132, ä
En me perdant sur internet pour mettre l’encodage de mon terminal en utf-8, j’ai finalement essayé d’entrer cette commande dans mon script de compilation : CHCP 65001>nul
(si j’ai bien compris ça force le terminal à utiliser de l’utf-8). Et là miracle, le terminal renvoie, pour les deux précédents codes :
encodage terminal : French_France.1252
strlen(chaine) : 2
chaine : Ä
chaine[0] : 195, Ã
chaine[1] : 132, „
Souvenez-vous, c’est bien un guillemet vers le bas qu’il fallait afficher, la table French_France.1252 a cette fois bien été respectée ! Mais aucune idée de pourquoi…
encodage terminal : C
strlen(chaine) : 2
chaine : Ä
chaine[0] : 195,
chaine[1] : 132,
Cette fois encore c’est logique car on a mis le terminal en utf-8 donc 'Ä' est interprété comme un seul caractère par ce-dernier.
Enfin, ma question : puisque manifestement la ligne char* encodage = setlocale(LC_ALL, "");
ne renseigne pas sur l’encodage utilisé dans le terminal, à quoi sert-elle ? Elle change bien quelque chose mais elle ne fait pas ce qu’il faudrait…
Et pourquoi le fait de passer le terminal en utf-8 a fait fonctionner mon bazar (surtout dans le premier cas) ?
Merci pour votre aide