从文件到表加载信息

时间:2014-12-26 15:32:54

标签: c

我想从文件中加载信息以存储在表格中,但我发现在加载信息时出现错误,并且函数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

2 个答案:

答案 0 :(得分: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)

  1. 请勿使用feof()来检测EOF条件。请改为检查输入函数的返回值。

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

  3. #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