我想从文件中加载信息以存储在表格中,但我发现在加载信息时出现错误,并且函数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
答案 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)
请勿使用feof()
来检测EOF条件。请改为检查输入函数的返回值。
赞@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