Formatage fscanf [Résolu]

Signaler
Messages postés
9
Date d'inscription
lundi 22 janvier 2007
Statut
Membre
Dernière intervention
23 janvier 2007
-
Messages postés
7
Date d'inscription
jeudi 26 avril 2007
Statut
Membre
Dernière intervention
23 mai 2007
-
bonjour, j'ai un probleme avec fscanf, il en prend pas en compte le formatage que je lui impose.

j'ai un fichier repertoire.txt dans lequel j'ai:


<hr size="2" width="100%" />
toto,titi,0123456789;


<hr size="2" width="100%" />
je veux ensuite récuperer mes donnée avec:


<hr size="2" width="100%" />

    fscanf(Pfichier,"%s,%s,%s;",contact[1].nom,contact[1].prenom,contact[1].numero);   
   
//affichage des données
    printf("\nNom: %s ",contact[1].nom);
    printf("\nPrenom: %s",contact[1].prenom);
    printf("\nNumero de telephone: %s",contact[1].numero);



<hr size="2" width="100%" />




maleureusement, il ne prend pas en compte mon formattage, et me stock tout dans contact[1].nom...

Y a t'il une erreure quelque part?

merci de m'aider!


xsybus

29 réponses

Messages postés
1137
Date d'inscription
lundi 17 novembre 2003
Statut
Membre
Dernière intervention
23 janvier 2016
21
Salut,
Je ne vois pas ce qui cloche dans fscanf() mais tu peux utiliser une solution plus longue si tu ne trouves pas la solution pour scanf :

FILE* file;
char bufLigne[256];
const char sep[] = ",\r\n";


// ouvre fichier


while( fgets(bufLigne, 256, file) != NULL )
{
    int numChamp = 0;
    char *token;
    token = strtok(bufLigne, sep);
 
    while( token != NULL )
    {
        switch( numChamp )
        {
        case 0:
            strcpy(contact[1].nom, token); 
            break;  
        case 1:
            strcpy(contact[1].prenom, token); 
            break;
        case 2:
            strcpy(contact[1].numero, token);
            break;
        } 
        token = strtok(NULL, sep);
        if( numChamp++ == 3 ) break;
    }


    if( numChamp != 3 ) //erreur
}


// ferme fichier
Messages postés
1137
Date d'inscription
lundi 17 novembre 2003
Statut
Membre
Dernière intervention
23 janvier 2016
21
Tu utilises pFichier et file en même temps !!
Messages postés
1137
Date d'inscription
lundi 17 novembre 2003
Statut
Membre
Dernière intervention
23 janvier 2016
21
Rajoute ";" dans sep[]
Messages postés
452
Date d'inscription
jeudi 4 décembre 2003
Statut
Membre
Dernière intervention
19 décembre 2008
10
fscanf tout comme les autres fonctions de la famille de scanf ont aussi une option de formatage un peu particulière pour ce genre d'expression.

fscanf(file, "%[^,],%[^,],...", chaine1, chaine2);

Avec ça, tu lis tout jusqu'à la première virgule (non comprise) et tu le mets dans chaine1, puis tu lis la virgule et de nouveau tout ce qui suit jusqu'à la virgule suivante et ainsi de suite.
Tu peux mettre plusieur caractère d'arrêt apres le ^ dans la chaine de formatage.
Vive le C
Savon
Messages postés
1137
Date d'inscription
lundi 17 novembre 2003
Statut
Membre
Dernière intervention
23 janvier 2016
21
Apparemment fscanf marcherait avec des espaces ex :

 fscanf(Pfichier,"%s, %s, %s;", ...)

pour une ligne dans le fichier :

toto, titi, 0123456789;

  
Messages postés
9
Date d'inscription
lundi 22 janvier 2007
Statut
Membre
Dernière intervention
23 janvier 2007

merci, je suis en train de tester ça, mais cela ne veux pas fonctionner, il plante direct à l'execution... c'est bien du C et non pas du C++?

voila mon prog en entier, avec ta modif:

<hr size="2" width="100%" />#include <stdio.h>
#include <stdlib.h>

int main()
{
   
    char nom_rep[50]="repertoire.txt";
   
//definition de la structure
    typedef struct repertoire repertoire;
    struct repertoire
    {
        char nom[30];
        char prenom[30];
        char numero[10];
    };
    repertoire contact[1000];
   
//definition du pointeur   
    FILE *Pfichier;
    Pfichier=fopen(nom_rep,"rb");
   
//recupération des données dans le fichier 
 
FILE* file;
char bufLigne[256];
const char sep[] = ",\r\n";

// ouvre fichier

while( fgets(bufLigne, 256, file) != NULL )
{
    int numChamp = 0;
    char *token;
    token = strtok(bufLigne, sep);
 
    while( token != NULL )
    {
        switch( numChamp )
        {
        case 0:
            strcpy(contact[1].nom, token);
            break; 
        case 1:
            strcpy(contact[1].prenom, token);
            break;
        case 2:
            strcpy(contact[1].numero, token);
            break;
        }
        token = strtok(NULL, sep);
        if( numChamp++ == 3 ) break;
    }
   
}

// ferme fichier
   
//affichage des données
    printf("\nNom: %s ",contact[1].nom);
    printf("\nPrenom: %s",contact[1].prenom);
    printf("\nNumero de telephone: %s",contact[1].numero);
    system("pause");
}
<hr size="2" width="100%" />
xsybus
Messages postés
1137
Date d'inscription
lundi 17 novembre 2003
Statut
Membre
Dernière intervention
23 janvier 2016
21
Essayes plutot un read texte :
fopen(nom_rep,"rt");
Messages postés
9
Date d'inscription
lundi 22 janvier 2007
Statut
Membre
Dernière intervention
23 janvier 2007

pour ta deuxieme proposition, j'ai testé avec 

fscanf(Pfichier,"%s, %s, %s;",contact[1].nom,contact[1].prenom,contact[1].numero);

avec ça dans mon fichier repertoire.txt:

toto, titi, 0123456789;

et il m'enregistre " toto, "dans contact[1].nom et rien dans le reste...

xsybus
Messages postés
9
Date d'inscription
lundi 22 janvier 2007
Statut
Membre
Dernière intervention
23 janvier 2007

<hr size="2" width="100%" />Essayes plutot un read texte :
fopen(nom_rep,"rt");<hr size="2" width="100%" />    cela ne change rien... merci de m'aider...

xsybus
Messages postés
9
Date d'inscription
lundi 22 janvier 2007
Statut
Membre
Dernière intervention
23 janvier 2007

<hr size="2" width="100%" />Tu utilises pFichier et file en même temps !!<hr size="2" width="100%" />
raaa putain mais quel con!!

merci beaucoup! ça marche!!!!

xsybus
Messages postés
1137
Date d'inscription
lundi 17 novembre 2003
Statut
Membre
Dernière intervention
23 janvier 2016
21
avec strtok ou fscanf ?
Messages postés
9
Date d'inscription
lundi 22 janvier 2007
Statut
Membre
Dernière intervention
23 janvier 2007

avec strtok, par contre j'ai le ";" à la fin du numero de téléphone qui s'affiche... galere...

merci de l'aide!

xsybus
Messages postés
9
Date d'inscription
lundi 22 janvier 2007
Statut
Membre
Dernière intervention
23 janvier 2007

merci!

xsybus
Messages postés
3212
Date d'inscription
lundi 7 novembre 2005
Statut
Membre
Dernière intervention
16 février 2009
15
Simple remarque. Un tableau commence à la valeur 0 et non à 1.


Dison que tu as ceci:

patente bidule[256];


bidule aura donc 256 patente qui s'étendront de 0 à 255.

Le premier sera bidule[0] et le dernier sera bidule[255]

C++ (@++)<!--
Messages postés
1137
Date d'inscription
lundi 17 novembre 2003
Statut
Membre
Dernière intervention
23 janvier 2016
21
saKingdom>> tu dis ça pour quel code ?
Messages postés
1137
Date d'inscription
lundi 17 novembre 2003
Statut
Membre
Dernière intervention
23 janvier 2016
21
Effectivement, en donnant une solution j'ai copié/collé le code de xsybus bètement. Il faut bien sur commencer un tab de char à [0] !
Messages postés
9
Date d'inscription
lundi 22 janvier 2007
Statut
Membre
Dernière intervention
23 janvier 2007

<hr size="2" width="100%" />fscanf tout comme les autres fonctions de la famille de scanf ont aussi
une option de formatage un peu particulière pour ce genre d'expression.

fscanf(file, "%[^,],%[^,],...", chaine1, chaine2);

Avec
ça, tu lis tout jusqu'à la première virgule (non comprise) et tu le
mets dans chaine1, puis tu lis la virgule et de nouveau tout ce qui
suit jusqu'à la virgule suivante et ainsi de suite.
Tu peux mettre plusieur caractère d'arrêt apres le ^ dans la chaine de formatage.
Vive le C<hr size="2" width="100%" />
tiens pas mal ça! je testerai ça tout à l'heure! merci!

xsybus
Messages postés
9
Date d'inscription
lundi 22 janvier 2007
Statut
Membre
Dernière intervention
23 janvier 2007

impec! ça marche merci!

xsybus
Messages postés
7
Date d'inscription
jeudi 26 avril 2007
Statut
Membre
Dernière intervention
23 mai 2007

Bonjour,

J'ai essayé la solution proposée ici, ayant le même genre de problème que xsybus, mais je n'ai pas réussi à m'en sortir.

Je dois lire un fichier sur plusieurs lignes se présentant ainsi :

"France";"Paris";"Le bourget";1845
"USA";"Chicago";"O'Hare";2286
"USA";"Atlanta";"Hartsfield-Jackson";2743
"USA";"New York";"JFK";4442
"USA";"San Francisco";"San Francisco";2286

Je souhaite placer chaque information entre les ; dans la variable d'une structure, le tout sous forme de liste chainée. J'ai el code suivant :

void open_log_aero(char * path){
    FILE* fich = fopen(path,"r");
    int i=0;
    int test=1;
    char pays[N];
    char ville[N];
    char nom_aero[N];
    int piste;
    test=fscanf(fich,"%[^;],%[^;],%[^;],%d\n",pays,ville,nom_aero,&piste);
    while(test!=EOF){
        printf("tour %d :: aeroport=%s\n",i,nom_aero);
        add_aero(pays,ville,nom_aero,piste);
        test=fscanf(fich,"%[^;],%[^;],%[^;],%d\n",pays,ville,nom_aero,&piste);
        i++;
    }
    fclose(fich);
}

La fonction add_aero se charge de la création de la liste chainée, N=20 et la structure aero se présente ainsi :

typedef struct _aero{
    char* pays;
    char* ville;
    char* nom_aero;
    int piste;
    struct _aero* suiv;
} * aero;

Je m'attends logiquement à ce que, dans ce cas, le logiciel m'affiche :

tour 0 :: aeroport : "Le Bourget"
tour 1 :: aeroport : "O'Hare"
tour 2 :: aeroport : "Hartsfield-Jackson"
etc.

au lieu de quoi j'ai une boucle infinie qui m'affiche :

tour XXXX :: aeroport : AAAAAAA[signe bizarre]"

Le tout marche très bien dans le cas d'éléments uniquement séparés par des espaces et enlever les guillemets n'y change rien.

Merci d'avance pour vos réponses ;)
Messages postés
452
Date d'inscription
jeudi 4 décembre 2003
Statut
Membre
Dernière intervention
19 décembre 2008
10
 test=fscanf(fich,"%[^;],%[^;],%[^;],%d\n",pays,ville,nom_aero,&piste);
Ca ne marchera pas, tu lis jusqu'à un point virgule, puis tu essaies de lire une virgule!

Essaie plutot ca:
 test=fscanf(fich,"%[^;];%[^;];%[^;];%d\n",pays,ville,nom_aero,&piste);

Et tu fais aussi un test sur la valeur que te retournes fscanf pour vérifier que tout est bien lu.

Vive le C
Savon