Erreur de chargement d'un fichier dans un tableau [Résolu]

Signaler
Messages postés
7
Date d'inscription
jeudi 14 novembre 2019
Statut
Membre
Dernière intervention
29 décembre 2019
-
[Dal]
Messages postés
5378
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
24 janvier 2020
-
Bonjour/soir, je débute en C,
Je souhaite charger un fichier de variables structurées dans un tableau mais lorsque je procède à sa lecture(seulement la chaîne de caractère de l'id), je me rend compte que le résultat n'est pas celui attendu. Si vous avez une idée je suis preneur.
Voici mon code et fichier :
    demande liredemande(FILE *fe) {
	demande ligne;
	fscanf(fe,"%s %s %s", ligne.iddemande, ligne.idetud, ligne.echelon);
	fgets(ligne.cite,20,fe);
	fscanf(fe,"%s",ligne.type);
	
	ligne.cite[strlen(ligne.type)-1]='\0';
	printf("%s \n",ligne.iddemande);
	//supprime le dernière caractère \n à la fin
	return ligne;
}


demande*chargementdemande(FILE *fe)
{
	demande*dem;
	while(feof(fe)==0)
		{	
			int i=0;
			dem=(demande*)malloc(sizeof(demande));
			if (dem==NULL) {printf("pb malloc\n");exit(1);}
			dem[i]=liredemande(fe);
			i++;
		}
	return dem;
}

typedef struct{
	char iddemande[4];
	char idetud[5];
	char echelon[4];
	char cite[20];
	char type[10];
}demande;


Mon fichier.don :
D001 E2058 6 Cezeaux T2
D002 E5862 4 Amboise chambre
D003 E9542 NULL Philippe Lebon studio
D004 E4698 NULL La Colombiere T1

résultat compilation :
D001E20586
E5864
E954NULL
E469NULL

2 réponses

Messages postés
5378
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
24 janvier 2020
849
Salut FifiAbesoindaide,

Pour le type
demande
:

typedef struct{
 char iddemande[4];
 char idetud[5];
 char echelon[4];
 char cite[20];
 char type[10];
}demande;


peux-tu indiquer quelles données doivent aller où sur un exemple de ligne comme "D001 E2058 6 Cezeaux T2" et sur un exemple comme "D003 E9542 NULL Philippe Lebon studio" et comment tu traites "NULL", et surtout nous dire ce que tu veux afficher au lieu du résultat que tu obtiens qui ne paraît pas être un "résultat de compilation" mais le résultat de l'affichage du programme exécuté.

Note aussi que pour stocker 4 caractères dans une chaîne en C, il te faut un tableau de 5
char
afin d'accueillir le caractère
'\0'
terminateur de la chaîne.

Dal
FifiAbesoindaide
Messages postés
7
Date d'inscription
jeudi 14 novembre 2019
Statut
Membre
Dernière intervention
29 décembre 2019

Bonjour Dal, merci de m'aider. Sur l'exemple précédent :"D003[iddemande] E9542[idetud] NULL[echelon] Philippe Lebon[cite] Studio[type]" / ""D001[iddemande] E2058[idetud] 6 [echelon] Cezeaux [cite] T2[type]" .

Le 'Null' fait parti du type echelon, en général un chiffre entre 0 et 7 est attendu mais il peut aussi ne rien avoir et donc je passe par 'NULL' que je n'interprète pas comme la fonction NULL en C, mais seulement comme une variable. Et oui effectivement vous avez raison c'est le résultat de l'affichage ^^.

Le problème est pour vérifier que mon fichier texte est bien rempli dans mon tableau, je passe par le printf de "liredemande" mais je me rend compte qu'au lieu d'obtenir dans mon tableau la répartition précedante, j'ai en fait "D001E20586[iddemande]" donc je sais d'avance que le reste de mon tableau sera faux puisqu'il a concaténer "D001[iddemande] E20586[idetud] 6[echelon]" dans iddemande.

Effectivement j'avais complétement oublier de prendre en compte le caractère terminateur de chaine dans ma variable structurée.

Cordialement,
Fifi.
Messages postés
7
Date d'inscription
jeudi 14 novembre 2019
Statut
Membre
Dernière intervention
29 décembre 2019

Je reviens pour dire que j'ai trouver les problèmes,
En premier : mon strlen dans 'liredemande' ne va pas, je l'ai remplacé par :
ligne.cite[strlen(ligne.cite)-1]='\0';

Puis mon deuxième est :
mon fgets :
gets(ligne.cite,20,fe);
. En effet pour mes lignes de mon fichier texte où un nom de cité possède un espace cela marche, mais pour ceux n'ayant pas d'espace il va prendre la chaine de caractère suivante, soit mon [type] de ma variable structuré.

Ducoup j'ai remplacé les espaces des noms de cités composés par des under-scores { _ }. Et maintenant ça marche. Le chargement est bon. Merci pour l'aide. Je passe le topic en résolu.

Cordialement,
Fifi.
[Dal]
Messages postés
5378
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
24 janvier 2020
849
Bravo !

Comme tu l'as relevé, certains noms de "cités" comprenaient des espaces, ce qui pouvait décaler ta lecture.

Si tu as la maîtrise du format de ton fichier de données, et que tu veux préserver les espaces dans les noms de cités, une autre solution est d'utiliser un caractère séparateur de champ non utilisé par ailleurs (par exemple le caractère point virgule) pour séparer tes données.

Ensuite, à la lecture, tu lis une ligne entière (jusqu'au retour à la ligne) et tu utilises la fonction standard C
strtok()
pour découper cette ligne selon les champs avec ce caractère séparateur.

Pour supprimer le caractère newline en fin de ligne, tu peux aussi faire ceci :

char *pos;
if ((pos=strchr(ligne, '\n')) != NULL)
    *pos = '\0';


cela permettra à ton programme de traiter correctement la dernière ligne, si celle-ci n'est pas elle-même terminée par un caractère newline (autrement, tu vas tronquer le dernier caractère).