Lecture et écriture sur plusieurs fichiers de données en mode séquentiel

Résolu
Smanyx Messages postés 10 Date d'inscription jeudi 5 février 2009 Statut Membre Dernière intervention 14 avril 2010 - 16 oct. 2009 à 05:34
victorcoasne Messages postés 1101 Date d'inscription jeudi 24 avril 2003 Statut Membre Dernière intervention 23 juillet 2023 - 22 oct. 2009 à 16:41
Salut à tous,

J'ai un problème pour lequel je désire votre aide. Voilà, il me faut écrire un program qui lit 3 fichiers de donnés:
[list]
employees.txt qui contient les rubriques suivantes: no_emp, nom, taux
Contenu:
001 John 19.75325
002 Nacha 17.60125
003 Mark 18.12356
004 Alain 20.82431
005 Solange 16.25634
/list
[list]
Wk13102009.txt : avec no_emp, jour1, jour2, jour3,jour4, jour5
Contenu:
001 9 9 9 10 9
002 9 9 8 8 9
003 9 9 9 9 9
004 7 8 8 9 9
005 9 9 9 9 9
/list
[list]
GeneralPay.txt : no_emp, paie_cumulee, taxe_cumulee, a_deduct_cumulee
(les montants sont du type float avec 6 positions après la virgule)
Contenu:
001 114563.367188 38200.050781 12115.719727
002 99397.281250 29632.150391 7111.390137
003 103297.453125 30184.080078 10095.730469
004 120938.453125 41424.019531 14081.179688
005 90438.250000 21437.169922 5678.950195
/list

Et après traitement des donnés, crée un quatrième fichier PaieSemaineCourante.txt, écrit les rubriques nécessaires et mets à jour le fichier GeneralPay.txt

Le mode d'accès à tous les fichiers est séquentiel.

Veuillez, s'il vous plait, en m'aidant considérer que mon niveau en programmation est encore de débutant.

Toutefois, j'ai pu écrire le programme que je soumets ci-dessous, mais il ne semble pas tourner correctement. Les données résultant de l'éxécution sont erronées, donc contraire à celles escomptées et l'écrire sur les fichiers ressemble plutôt à du charabia :)...

Après éxécution, je reçois le message d'erreur suivant: "Run-Time Check Failure #2 - Stack around the variable "no_emp" was corrupted"
Qu'est-ce que cela veut dire?

Aussi, si vous pouvez me pointer sur la bonne direction concernant de la documentation sur le sujet pour que j'approfondisse mes connaissances. Merci à tous.


/*Lire trois fichiers de données et écrire sur un quatrième fichier*/
  


#include<stdio.h>
#include<stdlib.h>

float paie(char*, float, float); /* function prototype */

int main(void)
{
char no_emp[4], nom[11]; 
int jour1, jour2, jour3, jour4, jour5;
float taux, salaire_brut, taxe, a_deduct, salaire_net, paie_cumulee, taxe_cumulee, a_deduct_cumulee, nbr_heures;  

FILE *fp1, *fp2, *fp3, *fp4;   
/*
fp1 = fopen ("employees.txt")
fp2 = fopen ("GeneralPay.txt")
fp3 = fopen ("Wk11102009.txt")
fp4 = fopen ("PaieSemaineCourante.txt")

*/

/* fopen ouvre le fichier. Exit le pgm en cas de problème */
if ((fp3 fopen("Wk13102009.txt", "r")) NULL)
{
printf("\n\tImpossible de lire Wk13102009.txt\n");
}
else
{	
if ((fp1 fopen("employees.txt", "r")) NULL)
{
printf("\n\tImpossible de lire employees.txt\n");
}
else
{
if ((fp2 fopen("GeneralPay.txt", "r+")) NULL)
{
printf("\n\tImpossible de lire GeneralPay.txt\n");
}
else
{
if ((fp4 fopen("PaieSemaineCourante.txt", "a")) NULL)
{
printf("\n\tImpossible de lire PaieSemaineCourante.txt.txt.\n");
}
else
{


while (!feof(fp3))
{


fscanf(fp3, "%s%d%d%d%d%d", no_emp, &jour1, &jour2, &jour3, &jour4, &jour5);
fscanf(fp1, "%s%s%f",   no_emp, nom, &taux);
fscanf(fp2, "%s%f%f%f", no_emp, &paie_cumulee, &taxe_cumulee, &a_deduct_cumulee );

nbr_heures = jour1 + jour2 + jour3 + jour4 + jour5;

salaire_brut = paie( no_emp, nbr_heures, taux);
 
taxe = salaire_brut * 0.30;

a_deduct = salaire_brut * 0.08;

salaire_net = salaire_brut - taxe - a_deduct;
                                						
//mise à jour des donnes cumulées dans GeneralPay.txt
paie_cumulee += salaire_net;
taxe_cumulee += taxe;
a_deduct_cumulee += a_deduct;

//écrire une ligne dans le fichier PaieSemaineCourante.txt
fprintf(fp4, "%s %s %.5f %2d %.5f %.2f %.2f %.2f%.2f\n", no_emp, nom, taux, 
nbr_heures, salaire_brut, salaire_net, paie_cumulee, taxe_cumulee, a_deduct_cumulee);

//écrire une ligne GeneralPay.txt
fprintf(fp2, "%s%.2f %.2f %.2f\n", no_emp, paie_cumulee, taxe_cumulee, a_deduct_cumulee);

                              	//remise des variables à zéro
nbr_heures = 0;
salaire_brut = 0;
taxe = 0;
a_deduct = 0;
salaire_net = 0;
 

}//fin de la boucle while
fclose(fp2);
fclose(fp1);
fclose(fp4);


}
}

fclose(fp3);	
}

}
printf("Program terminé sans normalement !\n\n\n");
system("pause");
return 0;

}



float paie( char *no_empo, float nbr_heures, float taux)
{

float s_brut;



s_brut = nbr_heures * taux;



return (s_brut);

}



No worries, i'll get there...

11 réponses

victorcoasne Messages postés 1101 Date d'inscription jeudi 24 avril 2003 Statut Membre Dernière intervention 23 juillet 2023 7
21 oct. 2009 à 14:01
Bonjour,

Afin que tu résolve le problème je te propose le code suivant :
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define DEBUG 1

bool convertir()
{
    // Déclaration des variables
    char no_emp1[3+1], no_emp2[3+1], no_emp3[3+1], nom[10+1];

    int jour1, jour2, jour3, jour4, jour5;

    float taux, salaire_brut, taxe, a_deduct, salaire_net, paie_cumulee,
    taxe_cumulee, a_deduct_cumulee, nbr_heures;

    FILE *fichierEmployees, *fichierGeneralPay, *fichierWk, *fichierSortie;

    // Ouverture des fichiers
    fichierWk = fopen("Wk13102009.txt", "r");
    if (fichierWk == NULL)
    {
        printf("\n\tImpossible de lire Wk13102009.txt\n");
        return false;
    }

    fichierEmployees = fopen("employees.txt", "r");
    if (fichierEmployees == NULL)
    {
        printf("\n\tImpossible de lire employees.txt\n");
        return false;
    }

    fichierGeneralPay = fopen("GeneralPay.txt", "r+");
    if (fichierGeneralPay == NULL)
    {
        printf("\n\tImpossible de lire GeneralPay.txt\n");
        return false;
    }

    fichierSortie = fopen("PaieSemaineCourante.txt", "a");
    if (fichierSortie == NULL)
    {
        printf(
            "\n\tImpossible de lire PaieSemaineCourante.txt.txt.\n");
        return false;
    }

    // Lecture et traitements des fichiers
    while (!feof(fichierWk))
    {

        // Récupération des données
        fscanf(fichierWk, "%s%d%d%d%d%d", no_emp1, &jour1, &jour2,
               &jour3, &jour4, &jour5);
        fscanf(fichierEmployees, "%s%s%f", no_emp2, nom, &taux);
        fscanf(fichierGeneralPay, "%s%f%f%f", no_emp3, &paie_cumulee,
               &taxe_cumulee, &a_deduct_cumulee);

        // Comparaison de la bonne correspondance
        if (strcmp(no_emp1, no_emp2)!=0 || strcmp(no_emp2, no_emp3)!=0)
        {
            printf("\n\tLes champs NO_EMP ne sont pas dans le "
                   "bon ordre dans les differents fichiers !\n");
        }

#if DEBUG == 1
        printf("NO_EMP : %s\tNOM : %s\tJOUR1 : %d\tJOUR2 : %d"
               "\tJOUR3 : %d\tJOUR4 : %d\tJOUR5 : %d"
               "\tPAIE_CUMULEE : %f\tTAUX : %f\tTAXE_CUMULEE : %f"
               "\tA_DEDUCT_CUMULEE : %f\n", no_emp1, nom, jour1, jour2,
               jour3, jour4, jour5, paie_cumulee, taux, taxe_cumulee,
               a_deduct_cumulee);
#endif
        
        // Traitement des données
        nbr_heures = jour1 + jour2 + jour3 + jour4 + jour5;
        salaire_brut = nbr_heures * taux;
        taxe = salaire_brut * 0.30;
        a_deduct = salaire_brut * 0.08;
        salaire_net = salaire_brut - taxe - a_deduct;
        
#if DEBUG == 1
        printf("NBR_HEURES : %f\tSALAIRE_BRUT : %f\tTAXE : %f"
               "\tA_DEDUCT : %f\tSALAIRE_NET : %f\n", nbr_heures,
               salaire_brut, taxe, a_deduct, salaire_net);

#endif

        // Mise à jour des donnes cumulées pour GeneralPay.txt
        paie_cumulee += salaire_net;
        taxe_cumulee += taxe;
        a_deduct_cumulee += a_deduct;
        
#if DEBUG == 1
        printf("GENERALPAY - \tPAIE_CUMULEE : %f\tTAXE_CUMULEE: %f"
        "\tA_DEDUCT_CUMULEE : %f\n", paie_cumulee, taxe_cumulee, a_deduct_cumulee);
#endif
        
#if DEBUG == 1
        printf("fichierSortie : %s %s %.5f %2d %.5f %.2f %.2f %.2f%.2f\n",
                no_emp1, nom, taux, nbr_heures, salaire_brut,
                salaire_net, paie_cumulee, taxe_cumulee,
                a_deduct_cumulee);
        printf("fichierGeneralPay : %s%.2f %.2f %.2f\n", no_emp1,
                paie_cumulee, taxe_cumulee, a_deduct_cumulee);
#else
        // Ecrire une ligne dans le fichier PaieSemaineCourante.txt
        fprintf(fichierSortie,
                "%s %s %.5f %2d %.5f %.2f %.2f %.2f%.2f\n",
                no_emp1, nom, taux, nbr_heures, salaire_brut,
                salaire_net, paie_cumulee, taxe_cumulee,
                a_deduct_cumulee);

        // Ecrire une ligne GeneralPay.txt
        fprintf(fichierGeneralPay, "%s%.2f %.2f %.2f\n", no_emp1,
                paie_cumulee, taxe_cumulee, a_deduct_cumulee);
#endif
        

    } // Fin de la boucle while

    fclose(fichierGeneralPay);
    fclose(fichierEmployees);
    fclose(fichierSortie);
    fclose(fichierWk);
}

int main(void)
{
    if (!convertir())
    {
        system("pause");
        return -1;
    }
    printf("Program termine normalement !\n");
    system("pause");
    return 0;
}


Merci et bonne prog,
@++

Victor
3
victorcoasne Messages postés 1101 Date d'inscription jeudi 24 avril 2003 Statut Membre Dernière intervention 23 juillet 2023 7
20 oct. 2009 à 13:35
Bonjour,

En mode debug ton projet plante où ?

Petite remarque : Il serait mieux de mettre tout la récupération / conversion dans une fonction afin de pouvoir quitter la fonction en cas d'erreur avec un return.
En effet il y a trop d'imbrications de if ce qui rend le code illisible.

Par exemple :
if ((fp3 fopen("Wk13102009.txt", "r")) NULL)
{
    printf("\n\tImpossible de lire Wk13102009.txt\n");
}
else
{
    [...]
}


Peut être remplacé par :
fp3 = fopen("Wk13102009.txt", "r");
if (fp3 == NULL)
{
   printf("\n\tImpossible de lire Wk13102009.txt\n");
   return false;
}
[...]
return true;


Merci et bonne prog,
@++

Victor
0
victorcoasne Messages postés 1101 Date d'inscription jeudi 24 avril 2003 Statut Membre Dernière intervention 23 juillet 2023 7
20 oct. 2009 à 22:29
Bonjour,

Je viens de compiler ton code avec le GCC de Dev-C++ et j'obtient le fichier suivant (sans erreur d'execution) :
001 John 19.75325  0 2.00000 -26815622308011076000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.00 -0.00 -0.00-2.00
7111.390137 Nacha 17.60125  0 -0.00000 2.00 2.00 0.002.00
.019531 Mark 18.12356  0 2.00000 26815622306875914000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.00 -26815622303019266000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.00 -2.00-26815622296621845000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.00
004 Alain 20.82431  0 -2.00000 0.00 2.00 -26815622333425424000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.00-2.00
1 Solange 16.25634  0 2.00000 -0.00 -2.00 -0.002.00


Merci et bonne prog,
@++

Victor
0
Smanyx Messages postés 10 Date d'inscription jeudi 5 février 2009 Statut Membre Dernière intervention 14 avril 2010
21 oct. 2009 à 00:50
Merci Victor pour ton intervention. Je prends en compte la remarque sur l'imbrication du code. D'autre part, le fichier généré est visiblement corrompu(j'obtiens moi aussi le même fichier en sortie). Au regard des fichiers en entrée, qu'est ce qui peut être la cause du dérapage?

Smanyx
0

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

Posez votre question
victorcoasne Messages postés 1101 Date d'inscription jeudi 24 avril 2003 Statut Membre Dernière intervention 23 juillet 2023 7
21 oct. 2009 à 13:27
Bonjour,

J'ai remarqué que ta fonction paie ne fait rien et prend un paramètre qui ne sert à rien.
Je te propose de la virer et de remplacer :
paie( no_emp, nbr_heures, taux);


Par ça :
nbr_heures * taux


Merci et bonne prog,
@++

Victor
0
Cyr62110 Messages postés 65 Date d'inscription vendredi 10 février 2006 Statut Membre Dernière intervention 21 octobre 2009
21 oct. 2009 à 13:32
Voici la solution pour retrouver la lecture des données :
fscanf(fp3, "%s%d%d%d%d%d", no_emp, &jour1, &jour2, &jour3, &jour4, &jour5);
fscanf(fp1, "%s%s%f", no_emp, nom, &taux);
fflush(fp2); //Vide le buffer
fscanf(fp2, "%s%f", no_emp, &paie_cumulee, &taxe_cumulee, &a_deduct_cumulee );

Bye
0
victorcoasne Messages postés 1101 Date d'inscription jeudi 24 avril 2003 Statut Membre Dernière intervention 23 juillet 2023 7
21 oct. 2009 à 13:43
Bonjour,

Le programme lit dans tes fichiers les lignes suivantes :
NO_EMP : 001    NOM : John      JOUR1 : 9       JOUR2 : 9       JOUR3 : 9	JOUR4 : 10      JOUR5 : 9       PAIE_CUMULEE : 114563.367188    TAUX : 19.753250	TAXE_CUMULEE : 38200.050781     A_DEDUCT_CUMULEE : 12115.719727
NO_EMP : 002    NOM : Nacha     JOUR1 : 9       JOUR2 : 9       JOUR3 : 8	JOUR4 : 8       JOUR5 : 9       PAIE_CUMULEE : 99397.281250     TAUX : 17.601250	TAXE_CUMULEE : 29632.150391     A_DEDUCT_CUMULEE : 7111.390137
NO_EMP : 003    NOM : Mark      JOUR1 : 9       JOUR2 : 9       JOUR3 : 9	JOUR4 : 9       JOUR5 : 9       PAIE_CUMULEE : 103297.453125    TAUX : 18.123560	TAXE_CUMULEE : 30184.080078     A_DEDUCT_CUMULEE : 10095.730469
NO_EMP : 004    NOM : Alain     JOUR1 : 7       JOUR2 : 8       JOUR3 : 8	JOUR4 : 9       JOUR5 : 9       PAIE_CUMULEE : 120938.453125    TAUX : 20.824310	TAXE_CUMULEE : 41424.019531     A_DEDUCT_CUMULEE : 14081.179688
NO_EMP : 005    NOM : Solange   JOUR1 : 9       JOUR2 : 9       JOUR3 : 9	JOUR4 : 9       JOUR5 : 9       PAIE_CUMULEE : 90438.250000     TAUX : 16.256340	TAXE_CUMULEE : 21437.169922     A_DEDUCT_CUMULEE : 5678.950195


Si c'est bien ce qu'il doit lire il y a sûrement une erreur de traitement par la suite.

Astuce : Quand ça ne marche pas toujours tester par petit bout et passer à la suite si c'est bon.

Merci et bonne prog,
@++

Victor
0
victorcoasne Messages postés 1101 Date d'inscription jeudi 24 avril 2003 Statut Membre Dernière intervention 23 juillet 2023 7
21 oct. 2009 à 13:55
Bonjour,

Voici le résultat des calculs suivi des nouvelles valeurs pour GeneralPay.txt :
NO_EMP : 001    NBR_HEURES : 46.000000  SALAIRE_BRUT : 908.649536       TAXE : 272.594849       A_DEDUCT : 72.691963    SALAIRE_NET : 563.362732
GENERALPAY -   PAIE_CUMULEE : 115126.726563    TAXE_CUMULEE: 38472.644531	A_DEDUCT_CUMULEE : 12188.412109
NO_EMP : 002    NBR_HEURES : 43.000000  SALAIRE_BRUT : 756.853760       TAXE : 227.056122       A_DEDUCT : 60.548302    SALAIRE_NET : 469.249329
GENERALPAY -   PAIE_CUMULEE : 99866.531250     TAXE_CUMULEE: 29859.207031	A_DEDUCT_CUMULEE : 7171.938477
NO_EMP : 003    NBR_HEURES : 45.000000  SALAIRE_BRUT : 815.560181       TAXE : 244.668060       A_DEDUCT : 65.244812    SALAIRE_NET : 505.647308
GENERALPAY -   PAIE_CUMULEE : 103803.101563    TAXE_CUMULEE: 30428.748047	A_DEDUCT_CUMULEE : 10160.975586
NO_EMP : 004    NBR_HEURES : 41.000000  SALAIRE_BRUT : 853.796753       TAXE : 256.139038       A_DEDUCT : 68.303741    SALAIRE_NET : 529.354004
GENERALPAY -   PAIE_CUMULEE : 121467.804688    TAXE_CUMULEE: 41680.160156	A_DEDUCT_CUMULEE : 14149.483398
NO_EMP : 005    NBR_HEURES : 45.000000  SALAIRE_BRUT : 731.535278       TAXE : 219.460587       A_DEDUCT : 58.522823    SALAIRE_NET : 453.551880
GENERALPAY -   PAIE_CUMULEE : 90891.804688     TAXE_CUMULEE: 21656.630859	A_DEDUCT_CUMULEE : 5737.473145


Est-ce que les valeurs sont bonnes ? (j'ai la flemme de calculer)

Merci et bonne prog,
@++

Victor
0
victorcoasne Messages postés 1101 Date d'inscription jeudi 24 avril 2003 Statut Membre Dernière intervention 23 juillet 2023 7
21 oct. 2009 à 19:40
Bonjour,

Si ton problème est résolu merci d'appuyer sur le bouton prévu à cet effet

Merci et bonne prog,
@++

Victor
0
Smanyx Messages postés 10 Date d'inscription jeudi 5 février 2009 Statut Membre Dernière intervention 14 avril 2010
22 oct. 2009 à 14:17
Merci beaucoup, Victor!

Mon problème est bel et bien résolu. Ton programme tourne parfaitement (à l' exception de l'affichage à l' écran qui laisse un peu à désirer, mais ça je vais pouvoir m'en occuper en formattant la sortie sur stdout). J'ai beaucoup apprécié ta contribution.

Merci aussi à cyr62110.

Coup de chapeau !

Smanyx
0
victorcoasne Messages postés 1101 Date d'inscription jeudi 24 avril 2003 Statut Membre Dernière intervention 23 juillet 2023 7
22 oct. 2009 à 16:41
Bonjour,

Il faut changer :
#define DEBUG 1


en :
#define DEBUG 0


Merci et bonne prog,
@++

Victor
0
Rejoignez-nous