2017-12-27 366 views
0

这个程序应该输入一个数字并计算学生之间的标记之间的平均值。这个程序只适用于以前的学生,但不适用于以下的程序。我认为那个fscanf有一个错误。任何人都可以帮忙吗?我不确定如何正确使用fscanf

int main() 
{ 
    FILE *cfPtr; 
    int matricola_in, matricola, nEsami, codEsame, voto; 
    char nome[20], cognome[20]; 
    int i, j, trovato = 0; 
    float somma = 0.0; 

    printf("Inserisci una matricola:\n"); 
    scanf("%d", &matricola_in); 

    if((cfPtr = fopen("studenti.txt", "r")) == NULL) 
     printf("Errore"); 

    while(!feof(cfPtr) || trovato != 1){ 
     fscanf(cfPtr, "%d%s%s%d\n", &matricola, nome, cognome, &nEsami); 
     if(matricola_in == matricola){ 
      trovato = 1; 
      for(i = 0; i < nEsami; i++){ 
       fscanf(cfPtr, "%d%d\n", &codEsame, &voto); 
       somma += voto; 
      } 
      printf("Media: %.1f\n", somma/nEsami); 
     } 
    } 

    fclose(cfPtr); 

    return 0; 
} 

编辑:数据的模样:

matricola nome cognome n.esami`<eol>` 
(for n.esami-rows)codice esame voto`<eol>` 
... 
+0

添加'studenti.txt'前几行的hexdump - 尝试'hexdump -C studenti.txt | head'。这可能会立即向您显示答案,但无论如何都会对其他人的回答有所帮助。 –

+1

数据是什么样的?也许你有一个学生多于或少于两个名称组件?你也没有把总和('somma')设回零。你永远不想用'feof'控制一个循环,而是检查'fscanf'的返回值,并且当它处理的字段少于请求的字段时,'feof'会告诉你原因是否到达文件末尾。 –

+0

编辑:数据看起来像:(matricola)(nome)(cognome)(n.esami) n.esami-rows :(codice esame)(voto)... – Teorema

回答

1

尚不清楚,但似乎该文件包含有四个或两个项目线的组合。
考虑阅读每一行。使用sscanf将该行解析为最多四个字符串。根据需要使用sscanf来捕捉线上的整数。如果有两个项目,则处理它们,如果trovato标志指示已找到匹配项。如果有四个项目,请查看是否匹配并设置trovato

int main() 
{ 
    FILE *cfPtr; 
    int matricola_in, matricola, nEsami, codEsame, voto; 
    char nome[20], cognome[20]; 
    char temp[4][20]; 
    char line[200]; 
    int result; 
    int i, j, trovato = 0; 
    float somma = 0.0; 

    printf("Inserisci una matricola:\n"); 
    scanf("%d", &matricola_in); 

    if((cfPtr = fopen("studenti.txt", "r")) == NULL) { 
     printf("Errore"); 
     return 0; 
    } 

    while(fgets (line, sizeof line, cfPtr)){//read a line until end of file 
     result = sscanf (line, "%19s%19s%19s%19s", temp[0], temp[1], temp[2], temp[3]);//scan up to four strings 
     if (result == 2) {//the line has two items 
      if (trovato) {// match was found 
       sscanf (temp[0], "%d", &codEsame); 
       sscanf (temp[1], "%d", &voto); 
       somma += voto; 
      } 
     } 
     if (result == 4) {//the line has four items 
      if (trovato) { 
       break;//there was a match so break 
      } 
      sscanf (temp[0], "%d", &matricola); 
      sscanf (temp[3], "%d", &nEsami); 
      if(matricola_in == matricola){//see if there is a match 
       trovato = 1;//set the flag 
      } 
     } 
    } 
    printf("Media: %.1f\n", somma/nEsami);//print results 

    fclose(cfPtr); 

    return 0; 
}