0

Hi I'm fairly new to c programming and I need to open a file read its contents make the program memorize them and from there pull specific information about employees.This is how the file looks:(there are 16 employees)

Tremblay Alain A 35.0 35.5 
Vachon Jean P 40.0 22.75 
...
St-amour Flavie P 40.0 25.0 

I just need to make the result appear once but it appears 16 times. I tried to put the printf ( % d..., k) outside the while but it does not work.

#include <stdio.h>
struct employes 
{
  char nom[25];
  char prenom[25];
  char poste;
  float heures;
  float salaire;
};

int main()
{
   struct employes tab[16];
   FILE *fic;

   if ((fic = fopen("employes.txt","r"))== NULL)
   {
       printf("Error! opening file");
       exit(1);         /* Program exits if file pointer returns NULL. */
   }

   int choix;
   printf("1. Afficher le nombre de programmeurs qui travaillent plus de 45 heures / semaine \n"
          "2. Afficher le nombre d'opérateurs qui travaillent plus de 40.50 heures / semaine \n"
          "3. Afficher le nombre de secrétaires qui travaillent plus de 35.00 heures / semaine\n"
          "4. Sortir\n");
   scanf("%d",&choix);

   int ch;
   int i=0;
   int k=0;
   do
   {
   switch(choix)
   {
      case 1:  while ( (ch = fgetc(fic)) != EOF)
               {
                  fscanf(fic,"%s %s %c %f %f\n", tab[i].nom, tab[i].prenom, &tab[i].poste, &tab[i].heures, &tab[i].salaire);

                    if(tab[i].poste == 'P' && tab[i].heures >= 45.00)
                    k++;
                    printf(" %d programmeurs travaillent plus de 45.00 heures/semaine\n",k);
               }
               break;

      case 2:  while ( (ch = fgetc(fic)) != EOF)
               { 
                   fscanf(fic,"%s %s %c %f %f\n", tab[i].nom, tab[i].prenom, &tab[i].poste, &tab[i].heures, &tab[i].salaire);

                     if(tab[i].poste == 'O' && tab[i].heures>=40.50)
                     k++;
                     printf(" %d operateurs travaillent plus de 40.50 heures/semaine\n",k);
               } 
               break;

      case 3:  while ( (ch = fgetc(fic)) != EOF) 
               {
                   fscanf(fic,"%s %s %c %f %f\n", tab[i].nom, tab[i].prenom, &tab[i].poste, &tab[i].heures, &tab[i].salaire);

                     if(tab[i].poste == 'S' && tab[i].heures>=35.00)
                     k++;
                     printf(" %d secretaires travaillent plus de 35.00 heures/semaine\n",k);
               } 
               break;

     case 4: printf("Au revoir!\n"); 
             break;
     default: printf("Desole, choix invalide.");
              break;

    }
}while(choix!=4);
   fclose(fic);



   system("pause");
   return 0;

}

The program prints this:

1. Afficher le nombre de programmeurs qui travaillent plus de 45 heures / semain
e
2. Afficher le nombre d'opÚrateurs qui travaillent plus de 40.50 heures / semain
e
3. Afficher le nombre de secrÚtaires qui travaillent plus de 35.00 heures / sema
ine
4. Sortir
1
0 programmeurs travaillent plus de 45.00 heures/semaine
0 programmeurs travaillent plus de 45.00 heures/semaine
0 programmeurs travaillent plus de 45.00 heures/semaine
0 programmeurs travaillent plus de 45.00 heures/semaine
0 programmeurs travaillent plus de 45.00 heures/semaine
0 programmeurs travaillent plus de 45.00 heures/semaine
0 programmeurs travaillent plus de 45.00 heures/semaine
0 programmeurs travaillent plus de 45.00 heures/semaine
0 programmeurs travaillent plus de 45.00 heures/semaine
0 programmeurs travaillent plus de 45.00 heures/semaine
0 programmeurs travaillent plus de 45.00 heures/semaine
0 programmeurs travaillent plus de 45.00 heures/semaine
0 programmeurs travaillent plus de 45.00 heures/semaine
0 programmeurs travaillent plus de 45.00 heures/semaine
0 programmeurs travaillent plus de 45.00 heures/semaine
0 programmeurs travaillent plus de 45.00 heures/semaine

but I want it to print this line only ONE TIME.

M p
  • 1
  • 1
  • Idea: *validate your input*, and [stop using `feof()` in a loop condition.](http://stackoverflow.com/questions/5431941/while-feof-file-is-always-wrong). I also question why `int i` is declared in *each case block*, thereby hiding the one you likely care about (which is never incremented, also a bug). – WhozCraig Oct 02 '14 at 02:27
  • Hi thank you for the comment may I ask what do you mean by input? and if I dont use feof() would this work: while ( fgets ( tab, sizeof tab, fic ) != NULL ) instead of my do while? – M p Oct 02 '14 at 02:39
  • I mean you never check the result of `fscanf` to know how many arguments it just parsed for you. Thats important, since you're otherwise blindly assuming they parsed correctly. And [**read the linked question**](http://stackoverflow.com/questions/5431941/while-feof-file-is-always-wrong) I provided to understand correct alternatives to incorrectly using `feof` in a loop condition. What you show in that comment looks *much* better than what you posted in the question. Just know you'll be `sscanf`-ing out of a line buffer rather than `fscanf`-ing out of a `FILE*` if you do it what way. – WhozCraig Oct 02 '14 at 02:41
  • I will search how do that thank you, but otherwise would this make the program work ? Do you see something else that might be wrong ? Because although it compiles my program does not show anything. – M p Oct 02 '14 at 02:50
  • int ch; while ( (ch = fgetc(fic)) != EOF) I used this one thanks to your link – M p Oct 02 '14 at 02:51

2 Answers2

0

This line ,the format of the fscanf "%s %s %c %f %f" should add an '\n' since there is new line before each new item.So maybe format ""%s %s %c %f %f\n" is right.

And when you read a string , do not use &.

fscanf(fic,"%s %s %c %f %f", &tab[i].nom, &tab[i].prenom, &tab[i].poste, &tab[i].heures, &tab[i].salaire);

should be

fscanf(fic,"%s %s %c %f %f\n", tab[i].nom, tab[i].prenom, &tab[i].poste, &tab[i].heures, &tab[i].salaire);

0

Actually, I didn't run your program but I guess your fscanf should be fscanf(fic,"%s %s %c %f %f", tab[i].nom, tab[i].prenom, &tab[i].poste, &tab[i].heures, &tab[i].salaire);

And the prototype of fgets in linux man page is that char *fgets(char *s, int size, FILE *stream);

So I think your fgets function should be fgets(buff, 40, fic) The reference I found is that http://linux.die.net/man/3/fgets

MaH
  • 3
  • 2