Formatage fscanf

Résolu
xsybus Messages postés 9 Date d'inscription lundi 22 janvier 2007 Statut Membre Dernière intervention 23 janvier 2007 - 22 janv. 2007 à 14:19
Arieltablett Messages postés 7 Date d'inscription jeudi 26 avril 2007 Statut Membre Dernière intervention 23 mai 2007 - 23 mai 2007 à 00:48
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

yann_lo_san Messages postés 1137 Date d'inscription lundi 17 novembre 2003 Statut Membre Dernière intervention 23 janvier 2016 26
22 janv. 2007 à 14:48
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
3
yann_lo_san Messages postés 1137 Date d'inscription lundi 17 novembre 2003 Statut Membre Dernière intervention 23 janvier 2016 26
22 janv. 2007 à 15:05
Tu utilises pFichier et file en même temps !!
3
yann_lo_san Messages postés 1137 Date d'inscription lundi 17 novembre 2003 Statut Membre Dernière intervention 23 janvier 2016 26
22 janv. 2007 à 15:31
Rajoute ";" dans sep[]
3
julienbj Messages postés 452 Date d'inscription jeudi 4 décembre 2003 Statut Membre Dernière intervention 19 décembre 2008 15
23 janv. 2007 à 00:41
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
3

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
yann_lo_san Messages postés 1137 Date d'inscription lundi 17 novembre 2003 Statut Membre Dernière intervention 23 janvier 2016 26
22 janv. 2007 à 14:54
Apparemment fscanf marcherait avec des espaces ex :

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

pour une ligne dans le fichier :

toto, titi, 0123456789;

  
0
xsybus Messages postés 9 Date d'inscription lundi 22 janvier 2007 Statut Membre Dernière intervention 23 janvier 2007
22 janv. 2007 à 14:58
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
0
yann_lo_san Messages postés 1137 Date d'inscription lundi 17 novembre 2003 Statut Membre Dernière intervention 23 janvier 2016 26
22 janv. 2007 à 15:03
Essayes plutot un read texte :
fopen(nom_rep,"rt");
0
xsybus Messages postés 9 Date d'inscription lundi 22 janvier 2007 Statut Membre Dernière intervention 23 janvier 2007
22 janv. 2007 à 15:05
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
0
xsybus Messages postés 9 Date d'inscription lundi 22 janvier 2007 Statut Membre Dernière intervention 23 janvier 2007
22 janv. 2007 à 15:07
<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
0
xsybus Messages postés 9 Date d'inscription lundi 22 janvier 2007 Statut Membre Dernière intervention 23 janvier 2007
22 janv. 2007 à 15:08
<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
0
yann_lo_san Messages postés 1137 Date d'inscription lundi 17 novembre 2003 Statut Membre Dernière intervention 23 janvier 2016 26
22 janv. 2007 à 15:10
avec strtok ou fscanf ?
0
xsybus Messages postés 9 Date d'inscription lundi 22 janvier 2007 Statut Membre Dernière intervention 23 janvier 2007
22 janv. 2007 à 15:23
avec strtok, par contre j'ai le ";" à la fin du numero de téléphone qui s'affiche... galere...

merci de l'aide!

xsybus
0
xsybus Messages postés 9 Date d'inscription lundi 22 janvier 2007 Statut Membre Dernière intervention 23 janvier 2007
22 janv. 2007 à 15:39
merci!

xsybus
0
SAKingdom Messages postés 3212 Date d'inscription lundi 7 novembre 2005 Statut Membre Dernière intervention 16 février 2009 15
23 janv. 2007 à 00:17
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++ (@++)<!--
0
yann_lo_san Messages postés 1137 Date d'inscription lundi 17 novembre 2003 Statut Membre Dernière intervention 23 janvier 2016 26
23 janv. 2007 à 00:28
saKingdom>> tu dis ça pour quel code ?
0
yann_lo_san Messages postés 1137 Date d'inscription lundi 17 novembre 2003 Statut Membre Dernière intervention 23 janvier 2016 26
23 janv. 2007 à 00:32
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] !
0
xsybus Messages postés 9 Date d'inscription lundi 22 janvier 2007 Statut Membre Dernière intervention 23 janvier 2007
23 janv. 2007 à 07:53
<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
0
xsybus Messages postés 9 Date d'inscription lundi 22 janvier 2007 Statut Membre Dernière intervention 23 janvier 2007
23 janv. 2007 à 09:12
impec! ça marche merci!

xsybus
0
Arieltablett Messages postés 7 Date d'inscription jeudi 26 avril 2007 Statut Membre Dernière intervention 23 mai 2007
6 mai 2007 à 23:06
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 ;)
0
julienbj Messages postés 452 Date d'inscription jeudi 4 décembre 2003 Statut Membre Dernière intervention 19 décembre 2008 15
7 mai 2007 à 09:16
 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
0
Rejoignez-nous