Voulant enregistrer un tableau de nombres compris entre 0 et 100, j'ai utilisé un fichier texte avec l'option "r" pour lire et "w" pour écrire. Tout semblait fonctionner jusqu'au jour où le nombre 26 a fait partie du tableau. A la lecture, 26 a été remplacé par -1 (comme si 26 était la valeur de EOF) et le reste du tableau est remplacé par 0.
J'ai résolu le problème en remplaçant les options "r" et "w" par "rb" et "wb" (fichier binaire), et pour le moment, ça a l'air de fonctionner, même avec 26!
Est ce qu'il y a une explication?
Voici le texte de mon programme, avec les deux résultats selon que le tableau contient ou non le nombre 26.
#include <stdio.h> #include <stdlib.h>
FILE* fichier=NULL; int i;
char liste_initiale[45] = {7,1,2,3,26,5,68,29}; // première liste contenant 26 //char liste_initiale[45]={7,1,2,3,37,5,68,29}; // deuxieme liste ne contenant pas 26 char liste_lue[45];
fichier=fopen("ecriture_de_nombres.zut","r"); x=fgetc(fichier); liste[0]=x; // x est indispensable i=0; // si je fait directement "liste[0]=fgetc(fichier)" do // ça ne marche pas { i++; x=fgetc(fichier); // idem liste[i]=x; } while (x!=EOF); fclose(fichier); }
int main() { ecriture(liste_initiale); // ecriture de la liste initiale dans un fichier lecture2(liste_lue); // lecture du fichier for (i=0;i<=liste_lue[0];i++) // affichage de la liste lue { printf("%d,",liste_lue[i]); } return 0; }
Résultat obtenu avec la liste ne contenant pas 26: 7,1,2,3,37,5,68,29, Résultat obtenu avec la liste contenant 26: 7,1,2,3,-1,0,0,0,
Merci de colorer votre code à l'aide du bouton Code
Les forums d'Openclassrooms disposent d'une fonctionnalité permettant de colorer et mettre en forme les codes source afin de les rendre plus lisibles et faciles à manipuler par les intervenants. Pour cela, il faut utiliser le bouton de l'éditeur, choisir un des langages proposés et coller votre code dans la zone prévue. Si vous utilisez l'éditeur de messages en mode Markdown, il faut utiliser les balises <pre class="brush: cpp;">Votre code ici</pre>.
Merci de modifier votre message d'origine en fonction.
Sous windows (en tout cas jusquà win7 inclus, et sous msdos avant lui), le caractère 0x1a (déc. 26) est considéré comme indicateur de fin de fichier si le fichier est ouvert en mode texte ("r" --- ou parfois "rt"). Sous linux, je ne sais pas, mais le test est simple à faire.
- Edité par edgarjacobs 28 mars 2020 à 14:15:01
On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent
Je travaille avec windows 10. Cela confirme ce que je pense: 26 doit être un code d'indication de fin de fichier, du moins pour les fichiers textes.
Je vais remettre mon programme en essayant d'utiliser ce qui est prévu pour ça:
#include <stdio.h>
#include <stdlib.h>
FILE* fichier=NULL;
int i;
char liste_initiale[45]={7,1,2,3,26,5,68,29}; // première liste ne contenant pas 26
//char liste_initiale[45]={7,1,2,3,37,24,98}; // deuxieme liste, contenant 26
char liste_lue[45];
/// ////////////////////////////////////////////
void ecriture(char liste[45])
{
fichier=fopen("ecriture_de_nombres.zut","w");
for (i=0;i<=liste[0];i++)
{
fputc(liste[i],fichier);
}
fclose(fichier);
}
/// ////////////////////////////////////////////
void lecture2(char liste[45])
{
char x;
fichier=fopen("ecriture_de_nombres.zut","r");
x=fgetc(fichier);
liste[0]=x; // x est indispensable
i=0; // si je fait directement "liste[0]=fgetc(fichier)"
do // ça ne marche pas
{
i++;
x=fgetc(fichier);
liste[i]=x;
}
while (x!=EOF);
fclose(fichier);
}
/// //////////////////////////////////////////////
int main()
{
ecriture(liste_initiale); // ecriture de la liste initiale dans un fichier
lecture2(liste_lue); // lecture du fichier
for (i=0;i<=liste_lue[0];i++) // affichage de la liste lue
{
printf("%d,",liste_lue[i]);
}
return 0;
}
Résultat obtenu avec la liste ne contenant pas 26: 7,1,2,3,37,5,68,29,
Résultat obtenu avec la liste contenant 26: 7,1,2,3,-1,0,0,0,
Pour commencer, tu mélanges allégrement la gestion d'un fichier en mode texte et en mode binaire.
Il y a une différence entre écrire des nombres et écrire des caractères. Le caractère 26 correspond à la commande SUB, le plus souvent interprétée comme une alternative de la touche "entrée".
Ton fichier ne contient quasiment que des commandes, ce qui est assez inutile pour un fichier en format texte :
Le jeu de fonctions fputc, fgetc sont à utiliser avec des caractères. Si tu veux stocker des nombres en mode texte, il y a fprintf() / fscanf().
Il y a une justification à traiter des fichiers en mode texte lorsque ceux-ci sont destinés à être lus ou édités par un utilisateur humain, ou pas mais qui sache lire ledit fichier. Si tu veux juste stocker des valeurs sur un octet, utilise le mode binaire.
Bonne continuation.
Edit : ta lecture va fonctionner juste en ouvrant en "rb" plutôt qu'en "r". Je n'en suis pas certain mais il me semble que ça supprime l'effet d'interprétation du caractère lu.
Résultat obtenu avec la liste contenant 26: 7,1,2,3,-1,0,0,0,
Normal, le fichier en ouvert en mode texte. Le 0x1a est donc intereprété comme indicateur de fin de fichier. Le seul moyen de "contourner" cela, c'est d'ouvrir le fichier en mode "rb":
Pour vérifier qu'un fichier est bien écrit en mode texte, il suffit de faire un type <nom-de-fichier>, dans un fenêtre de commande, on voit tout de suite ce qui se passe
D'autre part "fprintf() / fscanf()." ne paraît pas très sur, il vaut mieux un "fprintf() / fgets()." c'est plus sûr.
- Edité par joel76 28 mars 2020 à 17:06:19
Le crayon la gomme et le papier sont les meilleurs outils du programmeur !
D'autre part "fprintf() / fscanf()." ne paraît pas très sur, il vaut mieux un "fprintf() / fgets()." c'est plus sûr.
Pas Sûr ? C'est à dire ?
fscanf() et fgets() ne font rien d'équivalent. à la rigueur, on peut remplacer fgets() par fscanf() mais l'inverse n'est pas forcément vrai.
Effectivement, si le fichier n'est pas formaté selon les attentes du fscanf(), ça pose problème, mais le problème sera le même quand il s'agira de parser la chaîne de char extraite par fgets(), sans parler d'avoir à programmer le parseur avec des risques d'erreurs quand une fonction qui a fait ses preuves peut le faire à moindre coût.
N'importe qui peut modifier n'importe quel fichier, si le fichier est en binaire, il est encore possible de le modifier. Pour la petite histoire, j'encapsule mes ressources et ayant connaissance de la construction de la capsule, je peux remplacer une image par une autre dans le jeu en tapant au bon endroit. Je peux même me mettre 200 vies si je tape au bon endroit dans l'exécutable.
Bref, il n'y a pas de fichier "sûr", il doit être formaté selon les attentes du programme et c'est tout.
Oui, si le type est char. Mais j'ai écrit cela en pensant aussi aux types entier, et le second paramètre est la taille d'un élément à écrire. Et j'ai toujours employé employé 1 pour le nombre d'éléments à écrire, préférant donner le nombre d'octets à écrire.
- Edité par edgarjacobs 28 mars 2020 à 19:06:04
On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent
J'ai tendance à préférer fprintf()/fgets() suivi éventuellement d'un sscanf()
Le crayon la gomme et le papier sont les meilleurs outils du programmeur !
BIzarrerie dans la lecture d'un fichier (texte)
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent
Bonhomme !! | Jeu de plateforme : Prototype.
On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent
Le crayon la gomme et le papier sont les meilleurs outils du programmeur !
On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent
Bonhomme !! | Jeu de plateforme : Prototype.
On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent
Le crayon la gomme et le papier sont les meilleurs outils du programmeur !