2014-10-02 102 views
0

嗨我是相當新的c編程,我需要打開一個文件讀取它的內容使程序記住他們,並從那裏拉有關僱員的具體信息。這是文件的外觀:(有16名員工)printf問題

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

我只需要使結果出現一次,但它出現了16次。我試圖把printf(%d ...,k)放在外面,但它不起作用。

#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; 

} 

該程序打印這樣的:

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 

,但我想它來打印這條線一次。

+0

理念:*驗證輸入*和[停止使用'FEOF() '在循環條件。](http://stackoverflow.com/questions/5431941/while-feof-file-is-always-wrong)。我也質疑爲什麼'int i'是在*每個case block *中聲明的,從而隱藏了你可能關心的那個(它永遠不會增加,也是一個bug)。 – WhozCraig 2014-10-02 02:27:38

+0

嗨,謝謝你的評論,我可以問你輸入什麼意思?如果我不使用feof()會這樣工作: while(fgets(tab,sizeof tab,fic)!= NULL) 而不是我同時做? – 2014-10-02 02:39:47

+0

我的意思是你永遠不會檢查'fscanf'的結果來知道它爲你解析了多少個參數。這很重要,因爲否則你會盲目地認爲他們解析正確。和[**閱讀鏈接的問題**](http://stackoverflow.com/questions/5431941/while-feof-file-is-always-wrong)我提供了理解正確的替代方法,錯誤地使用'feof'在循環條件。您在該評論中展示的內容看起來比您在問題中發佈的內容要好得多。只要知道如果你以什麼方式進行操作,你就可以從行緩衝區中'sscanf'而不是'fscanf' - 從'FILE *'中執行。 – WhozCraig 2014-10-02 02:41:17

回答

0

因爲在每個新項目前都有新行,所以fscanf「%s%s%c%f%f」的格式應該增加一個'\ n'。 %S%C%F%F \ n 「是正確的。

而當你讀一個字符串,不要使用&

的fscanf(FIC,」 %s%S%C%F %f「,& tab [i] .nom,& tab [i] .prenom,& tab [i] .poste,& tab [i] .heures,& tab [i] .sala IRE);

應該是

的fscanf(FIC, 「%S%S%C%F%F \ n」 個,標籤[I] .nom,標籤[I] .prenom,&標籤[I] .poste,& tab [i] .heures,& tab [i] .salaire);

+0

它仍然沒有顯示任何東西:(當程序編譯它只是說按任意鍵繼續... – 2014-10-02 02:37:07

+0

我看到你用while循環來控制進程,但是當你使用fgets時,整行被讀取。 – mengyang 2014-10-02 03:59:20

+0

你可以在你的switch-case中試試默認值,看看程序是否達到它。 – mengyang 2014-10-02 04:00:06

0

其實,我沒有運行你的程序,但我想你的fscanf應該是fscanf(fic,「%s%s%c%f%f」,tab [i] .nom,tab [i] .prenom,& tab [i] .poste,& tab [i] .heures,& tab [i] .salaire);

fgets在linux手冊頁中的原型是char * fgets(char * s,int size,FILE * stream);

因此,我認爲你與fgets函數應該是與fgets(BUFF,40,FIC) 我發現的引用是http://linux.die.net/man/3/fgets