Probleme C programmation - système de sauvegarde
Fermé
hadrienlearn
-
Modifié le 2 févr. 2022 à 14:52
mamiemando Messages postés 33446 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 20 décembre 2024 - 2 févr. 2022 à 15:06
mamiemando Messages postés 33446 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 20 décembre 2024 - 2 févr. 2022 à 15:06
A voir également:
- Probleme C programmation - système de sauvegarde
- Logiciel de sauvegarde gratuit - Guide
- Restauration systeme - Guide
- Application de programmation - Guide
- Sauvegarde android - Guide
- Sauvegarde facile - Télécharger - Sauvegarde
2 réponses
Dalfab
Messages postés
706
Date d'inscription
dimanche 7 février 2016
Statut
Membre
Dernière intervention
2 novembre 2023
101
Modifié le 2 févr. 2022 à 14:56
Modifié le 2 févr. 2022 à 14:56
Bonjour,
Voilà quelques problèmes que j'ai vus dans ton code:
Je te propose d'utiliser plutôt les fonctions
Voilà quelques problèmes que j'ai vus dans ton code:
-
feof()
est trompeuse, elle n'indique pas si on est à la fin du fichier, elle indique si la dernière erreur est due à une fin de fichier atteinte. Lignes 11 à 13, il faudrait plutôt:
int int_data = fgetc(save); // fetc return un int qui contient le caractère ou EOF if ( int_data == EOF ) break; new_data = (char)int_data;
- ton tableau
data[]
n'est jamais initialisé. Donc tenter d'utiliserstrncat()
oustrcpy()
dessus risque de provoquer des choses curieuses, c'est peut-être la cause du plantage. Je te propose pour la ligne 3:
char data[MAX_NAME_CHAR] = ""; // le tableau contient une chaîne vide valide
- la manière de récupérer les données un caractère après l'autre n'est pas la plus intuitive. D'ailleurs tu ne remets jamais
data
à 0, tu vas donc récupérer "Hadrien" puis "Hadrien13215645" puis "Hadrien13215645Helory" puis .... - de plus tu sembles supposer qu'il y a un espace dans le fichier après le
tel[]
alors que c'est plutôt un retour chariot! - ton utilisation de
strncpy()
est plus qu'osée, c'est une fonction prévue pour concaténer 2 chaines (donc des tableaux dechar
qui se terminent par un '\0') et tu lui passes l'adresse d'un unique caractère lui imposant la taille max de 1. Elle va donc ajouter un caractère mais ne mettra pas le terminateur!. - tu ne fermes pas ton fichier!
Je te propose d'utiliser plutôt les fonctions
sscanf()et
fgets()pour extraire tes 2 mots. Ça donnerait (non testé et je suppose comme toi qu'il n'y a pas d'espaces dans les noms et comme toi je ne teste pas les éventuelles erreurs retournées par les fonctions utilisées):
void load_rep(pers rep[]) { int rep_id = 0; FILE *load = fopen( "save.data", "r" ); printf("Lancement de la lecture du fichier\n"); while (1) { char data[(MAX_NAME_CHAR - 1) + 1 + (9 - 1) + 1 + 1]; if (!fgets(data, (MAX_NAME_CHAR - 1) + 1 + (9 - 1) + 1 + 1, load)) // lire une ligne break; // plus rien à lire sscanf(data, "%s%s", rep[rep_id].name, rep[rep_id].tel); // extraire 2 mots de la ligne lue rep_id++; } printf("Fin de la lecture du fichier\n"); fclose(load); }
mamiemando
Messages postés
33446
Date d'inscription
jeudi 12 mai 2005
Statut
Modérateur
Dernière intervention
20 décembre 2024
7 812
Modifié le 2 févr. 2022 à 15:06
Modifié le 2 févr. 2022 à 15:06
Bonjour,
En complément à la réponse donnée :
Autres remarques mineures :
Bonne chance
En complément à la réponse donnée :
- Il faut contrôler si le fichier a été ouvert avec succès. Si c'est le cas tu peux le lire.Tu peux repartir de cette discussion (il faut juste interrompre le programme si
fp == NULL
). Cela sera plus élégant qu'une boucle while. - Je te recommande de partir sur un programme qui lit les lignes une par une dans un buffer, puis qui scan ce buffer avec
sscanf
comme le propose Dalfab. - En toute rigueur il faut contrôler le résultat de
sscanf
et vérifier que les deux valeurs ont bien été trouvées (sinon, c'est que la ligne de fichier est mal formée, et donc il faut l'ignorer). - Dans la réponse de Dalfab recopier directement le résultat de sscanf dans
rep[rep_id].name
est très cavalier car si la chaîne scanée est plus longue quesizeof(rep[rep_id].name)
, alors la chaîne recopiée va déborder sur les données qui suivent et/ou provoquer une erreur de segmentation. Il faut donc contrôler au préalable que la chaîne destination est suffisamment longue. Idem pourrep[rep_id].tel
. - Une fois le fichier lu, et seulement s'il a été ouvert avec succès, il faut le fermer.
Autres remarques mineures :
- Il est inutile de préciser
signed char
, c'est équivalent àchar
. En général on écritunsigned char
ouchar
selon qu'on veut un octet signé ou non signé. - Comme tes
id
sont positifs, les typer enunsigned int
(ouunsigned
en abrégé) serait avisé.
Bonne chance