2014-12-26 101 views
0

我想從文件加載信息以存儲在表中,但我發現在加載信息時出現錯誤,並且函數void charger_Etudiant(Etudiant *E)在存儲在文件中時不顯示信息有人幫我請:)從文件加載信息到表

typedef struct Etudiant 
{ 
    char nom[64]; 
    char prenom[64]; 

    char CNI[64]; 
    int sante; 
    int niveau_scolaire; 
    int Code_confidentiel; 
    int CNE; 
} Etudiant; 

的功能是:

void charger_Etudiant(Etudiant *E) 
{ 
    int i=0; 
    FILE *fichier = NULL; 
    fichier = fopen("Info_Etudiant.txt", "r"); 

    if (fichier != NULL) 
    { 
     while(i<2&&!feof(fichier)) 
     { 
     fscanf(fichier,"%d\t\t%s %s\t\t%d\t\t%s\t\t%d\t\t%d",&E[i].Code_confidentiel,E[i].nom,E[i].prenom,&E[i].CNE,E[i].CNI,&E[i].niveau_scolaire,&E[i].sante); 
     printf("%d\t\t%s %s\t\t%d\t\t%s\t\t%d\t\t%d",E[i].Code_confidentiel,E[i].nom,E[i].prenom,E[i].CNE,E[i].CNI,E[i].niveau_scolaire,E[i].sante); 
     i++; 
     } 
     fclose(fichier); 
    } 
} 

的是寫在下面的表格文件中爲例的信息,我想將它們存儲在一個表結構:

123 BADR HARI 10043720 SJ26825 1 3

+1

(a)顯示一些示例輸入。 (b)告訴我們你遇到什麼問題(有什麼錯誤?)。 – Rufflewind

+0

是否必須將其保存爲文本格式? –

+0

函數「」「void charger_Etudiant(Etudiant * E)」「」不會將信息存儲在文件中。這是問題 – Skimmo

回答

2

我不是scanf()fscanf()風扇。我更喜歡使用fgets()strtok()sscanf()來提取字段,儘管這裏atoi()已經足夠好了。 strtok()的一個優點是,如果字段分隔符改變,只需要一個調整。

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

#define STRLENG  63 

typedef struct Etudiant { 
    char nom [STRLENG+1]; 
    char prenom [STRLENG+1]; 
    char CNI [STRLENG+1]; 
    int sante; 
    int niveau_scolaire; 
    int Code_confidentiel; 
    int CNE; 
} Etudiant; 

int charger_Etudiant(Etudiant *E) { 
    int i=0; 
    char buff[512]; 
    char *tok; 
    char delims[] = "\t\n"; 
    FILE *fichier = NULL; 
    fichier = fopen("Info_Etudiant.txt", "r"); 
    if (fichier != NULL) { 
     while(fgets (buff, 512, fichier) != NULL) { 
      memset(&E[i], 0, sizeof(Etudiant)); 
      if (tok = strtok (buff, delims)) { 
       E[i].Code_confidentiel = atoi(tok); 
       if (tok = strtok (NULL, delims)) { 
        strncpy (E[i].nom, tok, STRLENG); 
        if (tok = strtok (NULL, delims)) { 
         strncpy (E[i].prenom, tok, STRLENG); 
         if (tok = strtok (NULL, delims)) { 
          E[i].CNE = atoi(tok); 
          if (tok = strtok (NULL, delims)) { 
           strncpy (E[i].CNI, tok, STRLENG); 
           if (tok = strtok (NULL, delims)) { 
            E[i].niveau_scolaire = atoi(tok); 
            if (tok = strtok (NULL, delims)) { 
             E[i].sante = atoi(tok); 
            } 
           } 
          } 
         } 
        } 
       } 
      printf("%d\t\t%s %s\t\t%d\t\t%s\t\t%d\t\t%d\n", 
        E[i].Code_confidentiel, E[i].nom, E[i].prenom, 
        E[i].CNE, E[i].CNI,E[i].niveau_scolaire,E[i].sante); 
      i++; 
      } 
     } 
     fclose(fichier); 
    } 
    return i; 
} 

int main() { 
    return 0; 
} 
1
  1. 不要使用feof()檢測EOF條件。相反,請檢查輸入函數的返回值。

  2. @Weather Vane建議使用fgets()

#define MAXINTLEN (20) 
// Use 2x size line buffer 
#define MAXLINELEN ((sizeof(Etudiant) + 4*MAXINTLEN) * 2) 

char buffer[MAXLINELEN + 2]; 

while (fgets(buffer, sizeof buffer, fichier) != NULL) { 
    int cnt = sscanf(buffer,"%d%63s%63s%d%63s%d%d", 
     &E[i].Code_confidentiel, E[i].nom, E[i].prenom, &E[i].CNE, 
     E[i].CNI, &E[i].niveau_scolaire, &E[i].sante); 
    if (cnt != 7) { 
    break; // scan error 
    } 
    printf("%d\t\t%s %s\t\t%d\t\t%s\t\t%d\t\t%d", 
     E[i].Code_confidentiel, E[i].nom, E[i].prenom, E[i].CNE, 
     E[i].CNI, E[i].niveau_scolaire, E[i].sante); 
    i++; 
} 

當掃描"\t\t"不一定掃描2個選項卡。 scanf()%[]除外)中的任何空格都會掃描任意數量的空格。代碼可以使用sscanf(buffer,"%d %63s %63s %d %63s %d %d", ...爲清晰,但它做同樣的事情。

說明符"%d""%s"反正消耗領先的空白。

總是限制字符串輸入。示例:%63s