Besoin d'aide Programmation C

Fermé
syrine - 13 juin 2013 à 17:13
[Dal] Messages postés 6198 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 13 décembre 2024 - 18 juin 2013 à 13:29
Bonjour,
J'ai besoin de votre aide svp.
il me faut faire un programme qui li les données à partir d'un fichier texte.
Pouvez vous m'aide, sachant que le fichier des données est le suivant:
NbDeDepots = 2;
NbDeClients= 3;
depl = [1,3,42,43,23,25,3,4,33,29,29,38,3,39,37,40,10,24];

WindowsC=[<192,192>,<356,356>,<418,418>];

DureeDeVisite=[139,37,32];

WindowsD=[<0,695>,<0,695>];

mon code source:
int main()
{
char data[2000];
char NbrDepots[2000];
char NbrClients[2000];
FILE*fichier=fopen("essai.txt","r");
int it = 1;
while (fgets(data,2000,fichier) != NULL) // On lit le fichier tant qu'on ne reçoit pas d'erreur (NULL)
{
switch (it)
{
case 1:
strcpy(NbrDepots,data);
int value1 = strlen(NbrDepots);
int Nbd=NbrDepots[value1-2]; //pour afficher la valeur 2
printf("le nombre de dépôts est : %c\n\n ",Nbd);
it++;
break;
case 2:
strcpy(NbrClients,data);
int value2 = strlen(NbrClients);
int Nbc=NbrClients[value2-2];//pour afficher la valeur 3
printf("le nombre de client est : %c\n\n ",Nbc);
it++;
break;

}
}

fclose(fichier);//*/
return 0;
}

mais dans le cas général, NbDeClients et NbDeDepots peuvent varier et par conséquent mon code ne fonctionnera plus,
il me faut une fonction de recherche par mot par exemple je cherche NbDeClients et ensuite je sauvegarde la valeur qui vient après.
merci d'avance.

2 réponses

[Dal] Messages postés 6198 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 13 décembre 2024 1 096
13 juin 2013 à 17:24
Salut syrine,

Tu peux essayer d'utiliser strstr :

http://www.cplusplus.com/reference/cstring/strstr/

Ensuite, tu explores la suite de la chaîne afin de vérifier qu'il y a bien :

- un ou plusieurs espaces à la suite (facultatifs)
- un signe '='
- un ou plusieurs espaces à la suite (facultatifs)
- un ou plusieurs caractères représentant des valeurs numériques à la suite (en les testant avec isdigit : http://www.cplusplus.com/reference/cctype/isdigit/)
- un ou plusieurs espaces à la suite (facultatifs)
- un point virgule


Dal
0
[Dal] Messages postés 6198 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 13 décembre 2024 1 096
Modifié par [Dal] le 13/06/2013 à 17:43
A la réflexion, on devrait pourrait essayer d'utiliser sscanf, ou même fscanf, avec des spécificateurs appropriés.

http://www.cplusplus.com/reference/cstdio/sscanf/
http://www.cplusplus.com/reference/cstdio/fscanf/


Dal
0
[Dal] Messages postés 6198 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 13 décembre 2024 1 096
Modifié par [Dal] le 13/06/2013 à 18:07
Par exemple en faisant comme cela :

#include <stdio.h>

int main(void)
{
    char * data = "NbDeDepots =    12345 ;";
    long int NbDeDepots = 0;

    if (sscanf(data, "NbDeDepots%*[ ]=%*[ ]%ld%*[ ];", &NbDeDepots) == 1)
    {
        printf("J'ai trouvé NbDeDepots : %ld\n", NbDeDepots);
    }
    else
    {
        printf("la chaîne analysée ne contient pas "
                "le masque recherché\n");
    }

    return 0;
}

Donne :

J'ai trouvé NbDeDepots : 12345
L'ennui est qu'il faut au moins un espace de part et d'autre du signe =, sinon le masque ne fonctionne pas.

Le C standard au travers de scanf et des fonctions de cette famille n'offre pas un réel support des regexp, il faudrait une bibliothèque externe pour cela (sous Linux, et systèmes POSIX, tu as regexp.h, en revanche).

Pour la syntaxe des spécificateurs de formats de sscanf, tu peux voir :

http://www.cplusplus.com/reference/cstdio/scanf/

Ce sont les mêmes.


Dal
0
[Dal] Messages postés 6198 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 13 décembre 2024 1 096
Modifié par [Dal] le 13/06/2013 à 18:20
De plus, dans l'exemple ci-dessus, sscanf ne va pas vraiment contrôler que la ligne se termine par ; ni qu'il y a un espace ou pas avant le ; car il n'y a pas d'autre variable à utiliser avec la chaîne donnée en entrée, c'est à dire que tu aurais le même résultat avec ou sans ; ou même si ta ligne contient "NbDeDepots = 12345tototititutu"


Dal
0
Je vous remercie pour votre réponse,
en fait, le fichier texte a été changé, et j'ai procédé d'une autre façon pour le lire, Lecture fonctionne, et j'ai besoin de remplir mes structure,
par exemple la fonction suivante:
void charge_duration(void)
{
int indice,a;
//printf("charge_duration \n");
read_mot(); // Duration
read_mot(); // [
read_mot(); // *
read_mot(); // ]
read_mot(); // :=
//read_mot();
do {
indice=atoi(mot);
// On a l'indice
read_mot();
a=atoi(mot);
// On a a
read_mot();
LesDurees[indice]=a*DFactor;
} while(strcmp(mot,TOKEN_PARAM));
return LesDurees;
}
permet de charger les durées qui sont de cette forme:
param Duration [*] :=
1 139
2 37
3 32
4 102
5 72
6 75
7 49
8 32
9 107
10 37
11 25
12 88
13 47
14 118
15 131
16 63
17 52
18 139
19 69
20 98
;
(première colonne : indice, deuxième colonne: durée à charger)
je voudrai remplir ma structure suivante:
typedef struct noeuds{
int ID; (identifiant ok j'arrive à le remplir)
int D;(durée)
// int a_i,b_i;
//int Type;
}Noeuds;
j'ai écris cette fonction pour remplir :
void remplir_donnees(int numero_noeud,Noeuds UnNoeud[Nb_Noeuds+1])
{
int i;
//int *duree;
//duree=charge_duration();
for(i=0;i<Nb_Noeuds;i++)
{
UnNoeud[numero_noeud].ID=i;
}
for(i=0;i<Nb_Clients;i++)
{
UnNoeud[numero_noeud].D=LesDurees[i];
}
}
pouvez vous me donner une idée sur le remplissage des structures dans ce cas?
je vous remercie d'avance
0
[Dal] Messages postés 6198 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 13 décembre 2024 1 096
Modifié par [Dal] le 18/06/2013 à 13:31
Salut syrinero,

1.

S'il te plaît, quand tu poses une question concernant le même sujet, utilise le même fil au lieu d'en créer un nouveau comme tu l'as fait là : https://forums.commentcamarche.net/forum/affich-28019523-programmation-c-lecture-d-un-fichier

En revanche, lorsque tu poses un nouvelle question, comme tu viens de le faire maintenant, qui n'a rien à voir avec la première, crée un nouveau sujet. Sinon, cela devient vite illisible, et ingérable pour ceux qui veulent t'aider.

2.

En ce qui concerne ton problème initial, tu pourrais aussi utiliser strtok, qui te permettrait d'évaluer tes chaînes en tokens en spécifiant les caractères délimitateurs.

http://www.cplusplus.com/reference/cstring/strtok/

Cela sera déjà plus robuste que ce que tu fais, où le code devient inadapté et ne renvoie pas d'erreurs si le format est erroné. Le plus robuste étant de faire comme indiqué là, https://forums.commentcamarche.net/forum/affich-28012006-besoin-d-aide-programmation-c#1 avec un contrôle strict de ce est sensé figurer dans la ligne parsée, dans l'ordre dans lequel il est sensé être.

3.

Je ne crois pas que cela soit très judicieux de remplir d'abord un tableau "Duration" que tu vas utiliser pour remplir un tableau de struct avec les mêmes données dedans.

J'utiliserai directement le tableau de struct.

Poste un nouveau sujet avec cette nouvelle question (donc, avec ton code et ta question ci-dessus), et je te donnerait un code d'exemple simple.

Si tu as de nouvelles questions sur ton sujet d'origine, ben vu que tu as créé deux sujets, j'imagine que c'est à toi de décider à qui tu réponds ... mais si tu me réponds, réponds ici.


Dal
0