Lecture et écriture dans un fichier .txt
Résolu/Fermé
Natsuko410
Messages postés
32
Date d'inscription
samedi 23 février 2019
Statut
Membre
Dernière intervention
11 mai 2019
-
Modifié le 4 mai 2019 à 14:28
Natsuko410 Messages postés 32 Date d'inscription samedi 23 février 2019 Statut Membre Dernière intervention 11 mai 2019 - 11 mai 2019 à 12:10
Natsuko410 Messages postés 32 Date d'inscription samedi 23 février 2019 Statut Membre Dernière intervention 11 mai 2019 - 11 mai 2019 à 12:10
A voir également:
- Lecture et écriture dans un fichier .txt
- Fichier rar - Guide
- Comment ouvrir un fichier epub ? - Guide
- Comment réduire la taille d'un fichier - Guide
- Fichier host - Guide
- Ouvrir un fichier .bin - Guide
1 réponse
[Dal]
Messages postés
6194
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
11 octobre 2024
1 092
6 mai 2019 à 17:35
6 mai 2019 à 17:35
Bonjour Natsuko410,
j'ai toujours le même problème
Lequel ?
Sinon, quelques réflexions en vrac :
1.
je pense qu'il y a une erreur dans le descriptif et qu'on devrait lire "si le libellé du thème 2 se trouve avant le libellé du thème 1 dans l'ordre lexicographique, elle renvoie un nombre >0."
Par rapport à ton code de comparerThemes(), tu n'utilises pas strcmp() alors qu'on te demande de le faire.
Quand je compare une chaîne "themeA" et "themeB", il me semble que "themeA" est avant "themeB" dans l'ordre lexicographique, et pas que les chaînes sont identiques.
2.
Tes boucles de lecture du contenu des fichiers sont inutilement compliquées.
Par exemple, ceci suffit pour compter les thèmes, avec, en plus un contrôle du succès de l'ouverture et une fermeture du fichier s'il a été ouvert :
Quand tu ouvres un fichier en mode d'ajout avec fopen() ("a" pour append, pas "at+"), tu n'as pas à te positionner dans le fichier pour écrire à la fin. Les opérations d'écriture se feront directement à la fin.
Je ne vois nulle part dans le code de ajouterTheme() que tu retournes l'identifiant du thème ajouté.
Je ne pense pas qu'il faille déterminer l'identifiant par rapport au nombre d'éléments... mais on a déjà eu cette discussion
Pour supprimer un thème du fichier, à mon sens, tu dois :
- ouvrir le fichier en lecture contenant les thèmes (themes.txt)
- ouvrir en écriture un fichier temporaire (temp.txt)
- lire dans le fichier themes.txt chaque ligne et l'écrire dans temp.txt sauf si la ligne contient ce que tu dois supprimer
- fermer themes.txt et temp.txt avec fclose()
- effacer themes.txt et renommer temp.txt en themes.txt
Dal
j'ai toujours le même problème
Lequel ?
Sinon, quelques réflexions en vrac :
1.
// compare les 2 thèmes reçus en paramètre. La comparaison se fait sur les libellés. // si le libellé du thème 1 se trouve avant le libellé du thème 2 dans l'ordre lexicographique, elle renvoie un nombre <0. // si le libellé du thème 2 se trouve avant le libellé du thème 1 dans l'ordre lexicographique, elle renvoie un nombre <0. // si les libellés sont identiques, elle renvoie 0. // Utilisez la fonction strcmp() int comparerThemes(struct Theme theme1, struct Theme theme2);
je pense qu'il y a une erreur dans le descriptif et qu'on devrait lire "si le libellé du thème 2 se trouve avant le libellé du thème 1 dans l'ordre lexicographique, elle renvoie un nombre >0."
Par rapport à ton code de comparerThemes(), tu n'utilises pas strcmp() alors qu'on te demande de le faire.
Quand je compare une chaîne "themeA" et "themeB", il me semble que "themeA" est avant "themeB" dans l'ordre lexicographique, et pas que les chaînes sont identiques.
2.
Tes boucles de lecture du contenu des fichiers sont inutilement compliquées.
Par exemple, ceci suffit pour compter les thèmes, avec, en plus un contrôle du succès de l'ouverture et une fermeture du fichier s'il a été ouvert :
fin = fopen(FICHIER_THEMES,"r"); /* Traitement */ if (fin) { while (fscanf(fin,"%d %s",&theme.identifiant,theme.libelle) == 2) nbThemes++; fclose(fin); }
Quand tu ouvres un fichier en mode d'ajout avec fopen() ("a" pour append, pas "at+"), tu n'as pas à te positionner dans le fichier pour écrire à la fin. Les opérations d'écriture se feront directement à la fin.
Je ne vois nulle part dans le code de ajouterTheme() que tu retournes l'identifiant du thème ajouté.
Je ne pense pas qu'il faille déterminer l'identifiant par rapport au nombre d'éléments... mais on a déjà eu cette discussion
Pour supprimer un thème du fichier, à mon sens, tu dois :
- ouvrir le fichier en lecture contenant les thèmes (themes.txt)
- ouvrir en écriture un fichier temporaire (temp.txt)
- lire dans le fichier themes.txt chaque ligne et l'écrire dans temp.txt sauf si la ligne contient ce que tu dois supprimer
- fermer themes.txt et temp.txt avec fclose()
- effacer themes.txt et renommer temp.txt en themes.txt
Dal
Modifié le 6 mai 2019 à 19:18
Et en fait, mon problème c'est ajouterTheme qui comme on peut le voir sur le screen de mon fichier ne fait pas ce qu'elle est censé faire, elle met le même identifiant aux différents thème et en plus, les recopies je ne sais pas combien de fois.
Pour la fonction comparerTheme, en effet, j'ai pas vérifié après celui qui l'a faite et du coup j'avais pas vu l'erreur, merci ^^
Pour ajouterTheme, je retourne i que j'ai incrémenter en lisant les enregistrements. Et pour l'identifiant, je vois pas comment je peux faire pour avoir l'identifiant correct parce qu'en fait, c'est vrai que j'ai oublié de le préciser je m'en excuse, mais je suis obligé de fonctionner de manière, comment dire... logique càd que je ne peux pas réellement supprimer un thème, je peux juste le remplacer par qqch comme par exemple : la chaine de caractère "DELETED" et dans nombreTheme j'identifie si c'est différent ou pas de cette même chaîne pour connaitre réellement le nombre de thème
Je sais pas si j'ai été super clair mais en gros c'est ça ^^
Modifié le 6 mai 2019 à 19:18
Peux-tu poster un exemple de code appelant cette fonction et créant un fichier erroné ?
je ne peux pas réellement supprimer un thème, je peux juste le remplacer par qqch comme par exemple : la chaine de caractère "DELETED"
OK, si c'est comme cela que tu dois fonctionner, mais il n'empêche que tu dois quand même passer par la création d'un fichier temporaire, le déroulement étant alors :
- ouvrir le fichier en lecture contenant les thèmes (themes.txt)
- ouvrir en écriture un fichier temporaire (temp.txt)
- lire dans le fichier themes.txt chaque ligne et l'écrire dans temp.txt sauf si la ligne contient ce que tu dois supprimer, auquel cas on écrit "DELETED"
- fermer themes.txt et temp.txt avec fclose()
- effacer themes.txt et renommer temp.txt en themes.txt
7 mai 2019 à 19:00
Voilà comment le projet est organisé :
Et voilà ce que ça donne :
Je sais pas comment ça se fait mais j'ai plus exactement le même problème que dans le "VRAI" projet, mais toujours est-il que je sais pas comment faire pour avoir le bon identifiant ^^
Encore une fois, merci pour ta réponse ça m'aide beaucoup, j'avance petit à petit mais j'avance :D
Modifié le 7 mai 2019 à 19:28
Tu pouvais juste faire un main avec un , cela aurait suffi, mais là c'est encore plus clair et c'est une bonne façon de circonscrire le problème pour toi aussi :-)
1.
Donc voilà ce qui la documentation de la fonction standard ftell() :
http://www.cplusplus.com/reference/cstdio/ftell/
long int ftell ( FILE * stream );
Get current position in stream
Returns the current value of the position indicator of the stream.
For binary streams, this is the number of bytes from the beginning of the file.
For text streams, the numerical value may not be meaningful but can still be used to restore the position to the same position later using fseek (if there are characters put back using ungetc still pending of being read, the behavior is undefined).
Autrement dit, pour les fichiers textes, tu ne peux pas te fier à cette valeur pour déterminer quoi que ce soit, et encore moins en faisant une division entière avec la taille en octets en mémoire d'une struct, qui n'a de sens que pour des données binaires si tu écrivais la totalité du contenu binaire de la mémoire (ce qui n'est pas le but recherché).
2.
Compte tenu des informations que tu as fournies précédemment, et notamment du fait qu'une ligne n'est jamais vraiment retirée du fichier, tu peux établir une stratégie simple d'attribution d'identifiant : l'identifiant d'un thème est le numéro de la ligne sur laquelle le thème est enregistré, en commençant par 1.
Cette stratégie peut être, par exemple :
- si tu ne gères pas le contenu en mémoire, de faire une première passe sur le fichier en lecture pour dénombrer le nombre de lignes stockées, y compris les lignes "DELETED", afin de déterminer le prochain numéro
- si tu gères le contenu en mémoire, de conserver l'information sur le nombre de lignes en mémoire vive du programme et d'incrémenter ce numéro lorsque tu ajoutes un thème
7 mai 2019 à 19:32