Hey bien le bonjours tout le monde !
Tout est dans le titre, mais je me dois de vous donnez plus d'explications. Donc voilà, j'aimerais savoir comment pourrais-je réserver des tableaux pour afficher mes accents qui sont dans un tableau.
Alors pour ce faire avec l'aide d'un tutoriel, j'ai fais une fonctionne Accent qui suffira d'appeler simplement pour que tous les accents de la phrase s'affiche. Cette méthode n'est pas exportable, donc elle fonctionnera que sur windows.
Voyez plutôt;
//Voici la fonctionne qui permettra d'afficher les Accents
const char * Accent(const char * mess)
{
static char retour [80];
CharToOem (mess,retour); // API Windows
return retour;
}
Ligne 7, le mot "static" permet à la fonction de retourner un pointeur sur une zone globale. Du coup, comment réserver un tableau comme;
const char* tab[] = {Accent(" Jôôùùèè\n\n\n"),Accent(" Rèèglàà\n\n\n"),Accent(" Qûûîîttééèè\n\n\n")} ;
Noté que j'ai mis "Accent" dans le tableau et que grâce à lui, il y a que le mot Jouer qui soit bien écrit. Ce que j'aimerais, c'est que justement, tous les accents dans ce même tableau soit pris en compte. Il faut réserver des tableaux et utiliser une fonction pour les remplir un après l'autre, non ??
Enfin, voilà, j'espère que vous avez compris et que vous aurez la réponse à ma question.
Je vous dis un grand merci et à bientôt.
T'aurais pu relire ton message pour arranger les balises :hap:
> Ligne 7, le mot "static" permet à la fonction de retourner un pointeur sur une zone globale. Du coup, comment réserver un tableau comme;
Apparemment tu es donc conscient que static char retour [80]; va réserver un tableau dans l'espace globale, donc oui c'est normal que tu ne puisse pas avoir plusieurs chaînes de caractère étant donné qu'il n'y a qu'un seul tableau disponible.
Sinon pour réserver un tableau tu as 2 possibilités :
* soit tu le déclare sur la pile dans une fonction, en allocation statique, mais la taille doit être fixée à la compilation (mais je crois que ça à changé avec la norme C99, à toi de voir si ton compilo l'accepte pour la portabilité de ton code). Attention une fois la fonction dans lequel le tableau a été créé terminé, ton tableau disparaît de la pile (enfin tu n'as plus à y toucher)
* Soit tu utilise l'allocation dynamique, avec malloc() / realloc() / free(), ce qui te permet de fixer la taille de ton tableau dynamiquement.
Dans tous les cas tu dois gérer chaque tableau que tu auras déclaré. Dans ton exemple :
<code>const char* tab[] = {Accent(" Jôôùùèè\n\n\n"),Accent(" Rèèglàà\n\n\n"),Accent(" Qûûîîttééèè\n\n\n")} ;
je ne suis pas sûr que tu puisse aller aussi vite, ou alors tu fais un malloc() dans ta fonction Accent() sans récupérer au final le pointeur, ce qui est à mon avis du mauvais code.
edit : tu as essayé de faire simplement const char* tab[] = {" Jôôùùèè\n\n\n", "Rèèglàà\n\n\n"," Qûûîîttééèè\n\n\n"} ; mais en encodant ton fichier source d'une certaine manière ?
Par contre j'y connais pas grand chose en ce qui concerne l'encodage, mais j'avais noté ceci sur le MDSN :
If the CharToOem function is being used as an ANSI function, the string can be translated in place by setting the lpszDst parameter to the same address as the lpszSrc parameter. This cannot be done if CharToOem is being used as a wide-character function. car un caractère est noté sur 1 octet en norme ANSI, ce qui pourrait te faciliter grandement la vie, mais sera peut-être un peu réducteur par rapport à ce que tu veux faire ?
Salut merci beaucoup pour ta réponse. J'ai pas tout compris...
Oui j'ai essayer de changer l'encodage directement dans le logiciel code::bloc. enfin, c'est pas fautes d'avoir essayer tout les encodage que code::block propose. En tout cas, je galère de trop, j'y connais rien à ça. Le pire de tout, c'est que je débute alors j'ai vraiment du mal.
Je veux simplement faire un petit jeu en console. Où il sera raconter une histoire où l'utilisateur aura des choix à faire etc...
Comment puis-je procéder ??
Le 23 novembre 2017 à 15:36:50 aAardvark a écrit :
Soit tu utilise l'allocation dynamique, avec malloc() / realloc() / free(), ce qui te permet de fixer la taille de ton tableau dynamiquement.
J'arrive pas à comprendre en faites.
Merci beaucoup pour ta réponse en tout cas.
C'est l'encodage de la console Windows qui pose problème, il n'a pas le même que l'encodage "graphique" de Windows, et a fortiori de ton éditeur.
Donc soit :
1. Tu mets ton éditeur avec le même encodage que celui de la console Windows,
2. Tu mets la console Windows avec le même encodage que celui de ton éditeur,
3. Tu convertis à la volée l'encodage de ton éditeur vers celui de Windows,
4. Si as des chaînes statiques, tu peux changer leur encodage en particulier dans le fichier en remplaçant les caractères qui posent problème (les non-ASCII) par la valeur correspondante.
Toi tu fais le 3 sur ce topic.
Quelques remarques :
- CharToOem peut renvoyer un code d'erreur, il faut le rattraper. Toujours tester les codes de retour. Du coup tu dois aussi implémenter un système de gestion d'erreur dans fonction.
- CharToOem peut poser des problèmes de sécurité, donc tu peux soit faire les vérifications en particulier sur la longueur de chaîne; soit utiliser des équivalents genre CharToOemBuff, mais ça demande un peu plus de travail.
- Si tu utilises seulement la méthode 3, pense à mettre un système de cache afin de ne pas effectuer des conversions pour rien.
- Tu devrais mettre une option à la compilation (ou alors dans ton programme) pour déterminer si la cible est la console Windows ou non. Sans même évoquer des questions de compatibilité, si quelqu'un exécute ton programme sous une autre console ou sur un environnement graphique, il peut avoir des problèmes d'affichage.
- Accent devrait être une macro, ou alors une fonction inline.
- Si tu ne veux pas avoir recours à de l'allocation dynamique, tu peux avoir une variable dans l'espace global d'une taille fixe (attention à bien vérifier que la taille de la chaîne à convertir est inférieure ou égale à cette taille fixe) mais si tu as un professeur il risque de ne pas être content.
Pour les accent je pense avoir trouver une solution, mais je me pose encore des question sur ça.
Sinon, il y a ce lien là aussi, mais je me demande si ça va correspondre à se que je cherche et si c'est portable.
https://stackoverflow.com/questions/1259084/what-encoding-code-page-is-cmd-exe-using
(J'ai pas encore essayer.)
#include <windows.h>
#include <stdio.h>
#define UNICODE 65000
int main(int argc, char *argv[])
{
SetConsoleCP(UNICODE);
SetConsoleOutputCP(UNICODE);
printf("éé èè àà êê ôô îî\n\n\n");
system("PAUSE");
}Pour les quelque remarques;
Je pense que je vais devoir encore bosser. J'avais pas pensais à tout ça (Oui, je débute hein)
Puis, je dois pensais aussi à essayer de corriger tout les Warning, j'en dois en avoir entre 15 - 30 je trouve ça énorme.
Si tu as le courage et me guider surtout n'hésite pas et je t'en serait vraiment reconnaissent. Pour l'heure j'apprends via internet et internet ne me résous pas tous les problèmes, je dois aussi chercher par moi même grâce à tout se que j'ai appris.
Merci beaucoup pour vos réponse, je vais garder cette page ouverte
.
Si ça marche, pense bien à remettre la codepage qu'il y avait avant. Et je ne sais pas ce qui se passe sur une console qui n'accepte qu'une seule codepage (ça existe au moins ?
)
Le codepage qu'il y avait juste avant ?? C'est-à-dire ??
Après oui, je ne sais pas non plus se que ça va faire sur une autre console. Puis, j'ai du modifier la fenêtre de ma console aussi et sélectionner la police "Consolas". Pour le moment ça fonctionne, chez moi. Avant d'allez plus loin faudrait que j'essai sur un autre pc.
Puis, je dois pensais aussi à essayer de corriger tout les Warning, j'en dois en avoir entre 15 - 30 je trouve ça énorme.
Oui c'est primordial, tu devrais en avoir aucun (ou alors très peu). Parfois c'est pas forcément important mais souvent il y a moyen de faire en sorte que les warnings ne s'affiche pas et que le compilo traite les choses correctement. Mais souvent ça peut indiquer des erreurs plus graves dans ton code.
Mais pense effectivement à bien te renseigner sur comment sont alloués tes variables / tableaux et comment ça se manifeste en mémoire, ainsi que leur portée, les mots-clef static, extern etc, c'est vraiment important pour avoir des bases solides en C et ne pas s'embrouiller
Et ce n'est pas si compliqué que ça (un peu au début certes)
par contre 49171 ![]()
- Accent devrait être une macro, ou alors une fonction inline.
Il y a une bonne raison pour cela selon toi ? Ou c'est juste pour indiquer que la fonction est courte ? J'apprends aussi d'une certaine manière ![]()
Le 23 novembre 2017 à 20:52:47 aAardvark a écrit :
Puis, je dois pensais aussi à essayer de corriger tout les Warning, j'en dois en avoir entre 15 - 30 je trouve ça énorme.
Oui c'est primordial, tu devrais en avoir aucun (ou alors très peu). Parfois c'est pas forcément important mais souvent il y a moyen de faire en sorte que les warnings ne s'affiche pas et que le compilo traite les choses correctement. Mais souvent ça peut indiquer des erreurs plus graves dans ton code.
oui, comme tu dis, le mieux c'est de pas en avoir ! J'ai bientôt fini tout les détail du jeux (avant de commencer à le programmer, j'ai préféré faire toutes les options externes, dans un .h que j'ai appeler fonction tout simplement) Une fois chose faite, je vais m'attaquer à tout les Warning's.
Le 23 novembre 2017 à 20:52:47 aAardvark a écrit :
Mais pense effectivement à bien te renseigner sur comment sont alloués tes variables / tableaux et comment ça se manifeste en mémoire, ainsi que leur portée, les mots-clef static, extern etc, c'est vraiment important pour avoir des bases solides en C et ne pas s'embrouillerEt ce n'est pas si compliqué que ça (un peu au début certes)
Oui oui, puis ça dois faire environs 1 semaines que j'apprends le C j'ai déjà terminer les chapitre de OpenClassRoom à plusieurs reprises pour bien assimiler se qui est expliquer. Y compris les chapitres sur la SDL et le petit jeux Sokoban Mario. Mais tout ça ne fais pas tout. Je veux dire par là qu'il y a encore énormément de choses à savoir. Alors j'ai voulu me faire un petit programme que pour moi ou pour distribuer aux copains en mode console.
En tout cas, je prend note de tout se que vous avez écrits et je vous dis un grand merci ![]()
PS; Dites moi, est-ce qu'il existe un Discord où sont réuni plusieurs personne qui programme dans les divers langages ??
Ça serait plus simple que de passé par des forums à l'avenirs, surtout si c'est un discord d'entraide.
Le 23 novembre 2017 à 20:52:47 aAardvark a écrit :
Il y a une bonne raison pour cela selon toi ? Ou c'est juste pour indiquer que la fonction est courte ? J'apprends aussi d'une certaine manière
Je ne sais pas si j'ai un niveau suffisant pour que tu apprennes, mais l'idée c'est que Accent va être utilisé plein de fois (c'est un jeu en mode texte, donc bon). Lorsque tu appelles une fonction tu fais un push et un pop sur la pile.
Certes aujourd'hui les ordinateurs sont très puissants; mais bon ce que l'auteur fait c'est un programme console, donc a priori rien ne dit que c'est fait pour un ordinateur puissant.
Macro ou inline remplace Accent comme si c'était un copier-coller à chaque occurrence.
Je vois beaucoup de programmeurs faire des trucs genre :
int i;
for(i = 0; i < 10; ++i)
action;
Je trouve cela assez inefficace (ce n'est que mon avis), car un programme de prétraitement tel que le préprocesseur pourrait détecter cela et faire un :
action;
action;
action;
...
action;
et économiser l'usage d'une variable : i, et surtout ne pas faire de jumps. Ça augmente la taille du programme mais aussi la vitesse d'exécution du programme. Selon le compilateur cela peut être optimisé ou non automatiquement.
Pour en revenir à Accent, je pense qu'une variable partagée de taille fixe serait efficace (bien veiller à gérer la taille), ou alors une allocation dynamique (même si c'est plus lent).
L'espace disque coûte moins cher que la mémoire vive (en euros), donc autant libérer le plus possible la dernière et faire des caches : ça accélère la vitesse des programmes, c'est une bonne pratique, et ça fait faire des économies. Après ce que je dis est à prendre avec des pincettes, parce qu'il me semble (après ça dépend) que les programmes sont chargés en mémoire; donc un programme plus gros mettra plus de temps à s'initialiser (théoriquement, après y'a 349 facteurs qui interviennent genre les swaps). Mais dans le cas de Accent ça va faire plein de push pop partout et elle sera probablement beaucoup utilisée. Je sais que c'est valable pour les petites fonctions, après je serais incapable de dire à quel moment une fonction n'est plus "petite".
Par exemple pour le for au-dessus, pour 10 je pense que ça se vaut, mais si je prends 1 000 000; je ne suis pas sûr que dupliquer le code soit plus performant (si tu as envie d'essayer je suis preneur !
)
Le 23 novembre 2017 à 20:32:43 Zanaki a écrit :
Le codepage qu'il y avait juste avant ?? C'est-à-dire ??Après oui, je ne sais pas non plus se que ça va faire sur une autre console. Puis, j'ai du modifier la fenêtre de ma console aussi et sélectionner la police "Consolas". Pour le moment ça fonctionne, chez moi. Avant d'allez plus loin faudrait que j'essai sur un autre pc.
Dans ton code tu changes la codepage en UNICODE (6500). Ça veut dire que si quelqu'un n'est pas en codepage 6500 lance ton programme, la console passe en 6500, puis y reste. Ton programme devrait remettre l'ancienne lorsqu'il termine.
Ce que je dis pourrait sembler inutile, mais quand tu vois des trucs genre ça :
https://www.gnu.org/software/libc/manual/html_node/Getopt-Long-Option-Example.html#Getopt-Long-Option-Example
static struct option long_options[] =
{
/* These options set a flag. */
{"verbose", no_argument, &verbose_flag, 1},
{"brief", no_argument, &verbose_flag, 0},
/* These options don’t set a flag.
We distinguish them by their indices. */
{"add", no_argument, 0, 'a'},
{"append", no_argument, 0, 'b'},
{"delete", required_argument, 0, 'd'},
{"create", required_argument, 0, 'c'},
{"file", required_argument, 0, 'f'},
{0, 0, 0, 0}
};
Ils ont mis une variable static dans le main pour que ça stocke dans un autre espace mémoire; ça sert pour les ordinateurs qui ont une petite mémoire. C'est un code d'exemple pour une bibliothèque qui gère les paramètres d'un programme.
Ce n'est que mon point de vue, mais c'est toujours une bonne pratique d'essayer d'optimiser la mémoire tant que faire se peut (c'est l'un des seuls avantages du C face à d'autres langages plus "productivites"); après il ne faut pas oublier que les compilateurs sont ultra-balèzes ces temps-ci, donc afficher l'assembleur généré est toujours très instructif. Le compilateur fait du bon boulot mais n'est pas parfait. ![]()
Pour en revenir au tout début de mon problème, je pense avoir trouver la solution et j'aimerais la partager avec vous pour avoir vos avis;
// Permet d'afficher les accents dans les phrases.
char * Accent (const char *mess)// Appelle de la fonction "Accent"
{
char *retour = malloc(100); // Assez grand pour la conversion
CharToOem(mess,retour); // API Window
return retour;
}
const char* tab[] = {Accent(" Jouééé\n\n\n"),
Accent(" Rèèèéééégle\n\n\n"),
Accent(" Quittèèè\n\n\n")};
printf (Accent("éé èè àà êê ôô îî\n\n\n"));Chez moi ça fonctionne plutôt bien, mais maintenant reste à savoir si c'est une bonne solution de le faire de cette façon.
Le 23 novembre 2017 à 21:41:09 49171 a écrit :
Certes aujourd'hui les ordinateurs sont très puissants; mais bon ce que l'auteur fait c'est un programme console, donc a priori rien ne dit que c'est fait pour un ordinateur puissant.
Si je programme en mode console, c'est justement pour apprendre encore et encore. Une fois que j'aurais assimiler le plus de choses possible, une fois que je serais moins perdu avec toutes ces fonctions, expression, code etc... Je pense que là, je pourrais m'attaquer a quelque chose de plus important. Je pense qu'il faut bien commencer par quelque chose, si j'entame directement le vif du sujet, je vais pas aller bien loin.
Dans tout les cas, je prends note de toutes cette conversation que je relirais. à plusieurs reprise pour bien comprendre le fonctionnement de tout se qui est expliquer.
Je vous dis un grand merci pour toutes vos réponses et j'attends de vos nouvelles.
Bonne soirée.
49171
C'est surtout qu'il me semble qu'actuellement les bons compilateurs arrivent à optimiser ce genre de chose par eux-même il me semble
Enfin je ne sais pas trop mais j'avais entendu dire que les compilateurs pouvait gérer les inline eux-même, étant assez balèze comme tu dis, mais bon dans tous les cas en embarqué ça a sans doute son utilité ![]()
Après dans le cas des boucles for() courtes et fixe, pourquoi pas, mais bon c'est vraiment aller chercher les microsecondes voire moins, là encore en embarqué pourquoi pas, et encore ![]()
Zanaki
Je ne pense pas que ce que tu as écris pose vraiment problème, mais tu risques quand même de te faire taper sur les doigts si quelqu'un lit ton code
edit: peut-être pas tant que ça en fait
En général quand on alloue de la mémoire avec malloc() on la libère avec free() pour éviter les fuites de mémoire, mais c'est en fait assez subjectif si tu comptes garder tes données jusqu'à la fin du programme, donc tu peux laisser comme ça je pense, tant que tu sais ce que tu as allouer et que tu le maîtrises https://stackoverflow.com/questions/6346969/there-is-no-point-in-freeing-blocks-at-end-of-program
Après si tu avais été sûr (ou si tu avais fixé comme condition) que ton texte était en ANSI (1 octet / caractère), ça te simplifierait le problème comme je te l'ai dit, mais ça te limite d'un autre côté effectivement.
Compile en -O3 et regarde l'asm tu vas avoir une surprise aAardvark.
Sinon l'auteur, il faut que tu testes si tes fonctions ont réussi (malloc, CharToOem, printf, ...).
Il faut aussi tester que la taille de ta chaîne n'est pas plus grande que 100, sinon c'est un overflow.
J'ai encore fais des rehcerche et essayer d'amélioré se petit programme pour les accents, dites moi se que vous en pensez s'il vous plait;
char * Accent (const char *mess)// Appelle de la fonction "Accent"
{
char *retour = malloc (strlen(mess)+1); // Assez grand pour la conversion
CharToOemBuff(mess,retour, strlen(mess)+1); // API Window
return retour;
}
Sachez que si je rajouter un printf(retour) ou un free(retour) Le programme se lance mais à l'intérieur tout bug.
Si je rajoute les deux commandes cité plus haut, alors le programme cesse de fonctionner.
Par contre, je peux rajouter les deux fonctions en dessous de return, mais là, je pense que ça devient inutile.
Faut savoir aussi que si j'enlève juste le return le programme cesse de fonctionner.
C'est déjà mieux.
Encore une fois, il faut tester le retour de malloc (qui peut échouer) et de CharToOem (qui peut échouer aussi).
Voir la documentation (return value) :
- https://www.tutorialspoint.com/c_standard_library/c_function_malloc.htm
- https://msdn.microsoft.com/en-us/library/windows/desktop/ms647494(v=vs.85).aspx
- https://www.tutorialspoint.com/c_standard_library/c_function_strlen.htm
- Il faut aussi que tu testes dans ta fonction que la pramètre "mess" n'est pas un pointeur NULL. Sinon lorsque tu vas essayer de le déréférencer tu vas avoir des problèmes.
- strlen ne prend pas en compte le '\0' de fin (voir la doc), donc c'est très bien d'avoir mis le +1.
Cependant tu appelles deux fois la fonction strlen(). Un appel de fonction est assez lourd, donc tu peux optimiser en créant une variable "taille", que tu réutilises ensuite.
- Ton compilateur est intelligent, mais normalement en langage C lorsque tu appelles malloc, la fonction malloc renvoie un (void *) (voir la doc). Toi tu veux un (char *), donc il faut faire la conversion.
- Enfin, un cas vraiment vicieux peut se produire.strlen est implémentée de manière à parcourir la mémoire jusqu'à ce qu'elle trouve un '\0'. Cependant si je donne un tableau de char dont le dernier caractère n'est PAS un '\0', alors la chaîne va "déborder" jusqu'à ce qu'elle en trouve un.
Si par exemple au lieu d'avoir mess qui vaut : 'H', 'e', 'l', 'l', 'o', '\0', j'ai 'H', 'e', 'l', 'l', 'o', alors un problème peut se produire.
Cela ne pose pas de problème particulier, sauf dans le cas subtil où strlen sort de la mémoire du programme. Par défaut les systèmes d'exploitation empêchent les programmes de lire et écrire dans la mémoire hors d'eux-mêmes (ce qui semble logique par raison de sécurité). Cependant que se passe-t-il si le prochain octet de mémoire juste en-dehors du programme est un caractère nul '\0' ?strlen va essayer de lire cette valeur, ce qui (après ça dépend du système d'exploitation) va résulter en un crash.
De même, si les accès en lecture sont permis, mais les accès en écritures interdits, CharToOem va donc essayer d'écrire sur ce caractère '\0' en dehors du programme, ce qui va résulter en un crash.
https://stackoverflow.com/a/4132870
https://stackoverflow.com/a/31429369
https://stackoverflow.com/questions/9372936/can-we-assign-a-value-to-a-given-memory-location
Je connais mal Windows, mais sous les systèmes UNIX il est possible de vérifier si la mémoire peut-être écrite ou non :
https://stackoverflow.com/questions/14433468/how-can-i-check-whether-a-memory-address-is-writable-or-not-at-runtime
Je ne sais pas comment faire sur Windows.
-Pour finir, fprintf peut planter aussi (c'est assez mal foutu que la fonction qui affiche les messages d'erreur puisse échouer, mais bon...)
https://www.tutorialspoint.com/c_standard_library/c_function_fprintf.htm
Donc j'ai créé une variable globale "fprtf".
enum accent_erreur
{
DEFAUT = 0,
ACCENT_MESS_NULL_FPRTF = 1,
ACCENT_MALLOC_FPRTF = 2,
ACCENT_C2OEM_FPRTF = 3,
AFF_ACCENT_PRTF = 4
};
enum accent_erreur fprtf;
char *Accent(const char *mess)
{
// On réinitialise la variable.
fprtf = DEFAUT;
// On s'assure que le pointeur n'est pas NULL.
if(mess != NULL)
{
if(fprintf(stderr, "[Accent] : Le paramètre `mess` ne doit pas être NULL.\n") < 0)
fprtf = ACCENT_MESS_NULL_FPRTF;
exit(EXIT_FAILURE);
}
// size_t est un type optimisé pour contenir une taille de données.
// Grosso-modo c'est un entier positif. strlen() renvoie un size_t (cf. la doc).
size_t taille = strlen(mess) + 1; // Le fameux "cas vicieux" peut se produire pour la lecture.
// Ne pas oublier la conversion.
char *retour = (char *) malloc(taille);
// On teste si malloc échoue ou non.
if(retour != NULL)
{
if(fprintf(stderr, "[Accent] : L'allocation dynamique a échoué.\n") < 0)
fprtf = ACCENT_MALLOC_FPRTF;
exit(EXIT_FAILURE);
}
// Il faut maintenant tester la valeur de retour CharToOemBuff.
// Le fameux "cas vicieux" peut se produire pour l'écriture.
if(CharToOemBuff(mess, retour, taille) == 0)
{
// Théoriquement fprintf peut échouer, donc il vaut mieux faire
// free avant au cas où.
free(retour); // Ne pas oublier de libérer la mémoire.
if(fprintf(stderr, "[Accent] : CharToOemBuff a échoué.\n") < 0)
fprtf = ACCENT_C2OEM_FPRTF;
exit(EXIT_FAILURE);
}
return retour;
}
Et bien sûr lorsque tu utilises Accent, il faut ensuite libérer la mémoire :
char *c = Accent("éèàâêîë");
if(fprtf != 0)
{
// Oh oh, c'est une sacrée erreur que l'on a ici.
}
printf("%s\n", c);
free(c);
Tu peux créer une fonction d'affichage automatisée qui s'occupe de libérer la mémoire pour toi :enum accent_erreur afficher_accent(const char *t)
{
char *c = Accent(t);
if(printf("%s\n", c) < 0)
{
if(fprtf == DEFAUT || fprtf > 2)
free(c);
return AFF_ACCENT_PRINTF;
}
free(c);
return fprtf;
}
Zut. Faut remplacer tous les exit(EXIT_FAILURE); par des return NULL; dans Accent, sinon toute la gestion des erreurs que j'ai fait derrière ne marche pas bien évidemment.
Je n'ai pas testé le programme (je ne suis pas sous Windows) donc je te laisse débuguer. Normalement si tu comprends le principe tu ne devrais pas avoir de mal.
N'hésite pas à faire des recherches Google si j'utilise des principes que tu ne connais pas.
Wahhhh Merci pour les réponses et toutes ces explications ! C'est vrai qu'il y a pas mal de choses que je ne comprends pas, mais c'est pas grave, je vais étudier tout le contenu pour comprendre l'intégralités des explications et du code que tu as écrit.
Juste une question; Est-ce que ça passera tout ça en cpp ??
Encore une fois, il faut tester le retour de malloc (qui peut échouer) et de CharToOem (qui peut échouer aussi).
Qu'est-ce que tu enttends par tester ?? Tu veux bien dire faire des fonctions qui permet justement de savoir si tel ou tel chose fonctionne correctement sinon, la chose en question t'envoie un message d'erreur ??
Ton compilateur est intelligent, mais normalement en langage C lorsque tu appelles malloc, la fonction malloc renvoie un (void *) (voir la doc). Toi tu veux un (char *), donc il faut faire la conversion.
D'après se que j'ai lu à chaque fois que tu appel un "malloc" il faut toujours rajouter un free() pour justement libéré la mémoire (Si je ne dis pas de bêtise)
J'ai du mal à comprends quand tu explique à propos de caractère \0
- Enfin, un cas vraiment vicieux peut se produire.
strlen est implémentée de manière à parcourir la mémoire jusqu'à ce qu'elle trouve un '\0'. Cependant si je donne un tableau de char dont le dernier caractère n'est PAS un '\0', alors la chaîne va "déborder" jusqu'à ce qu'elle en trouve un.
Si par exemple au lieu d'avoir mess qui vaut : 'H', 'e', 'l', 'l', 'o', '\0', j'ai 'H', 'e', 'l', 'l', 'o', alors un problème peut se produire.
En faite, j'ai compris le principe, mais se que je comprends pas c'est le caractère que tu désigne étant \0 Qu'est-ce que ça représente ??
Dans le premier code que tu m'as envoyer, je dois créer un fichier .h ou du moin, je peux créer un fichier .h nommé fprtf. par exemple.
Tu peux créer une fonction d'affichage automatisée qui s'occupe de libérer la mémoire pour toi :
J'aime bien cette idée. Ça ne te dérange pas que je m'inspire sur tout se que tu nous a envoyer ??
Je te dis encore une fois un grand merci pour le temps que tu m'as donner. Parce que mine de rien, c'est du boulot tout ça.