похоже, что у вас неправильно настроена структура, чтобы обрабатывать данные, которые вы хотите прочитать из своего файла. Ваши данные были:
name:score1:score2:score3:score5:lettergrade
структуру, которая имеет смысл (с учетом многочисленных баллов) будет:
typedef struct {
char name[MAXNM];
int id;
int scores[NGRDS];
float ave;
char grade;
} student;
(вы никогда не приходилось где id
приходит и я оставлю его использовать для разделения name
в first
, last
, так как ваш первоначальный вопрос заданный name
и ваши последние правки добавлены first
, last
)
Что с lear - вы хотите прочитать свой файл данных в struct
и вычислить ave
(средний) из прочитанных классов (который должен быть типом с плавающей запятой, а не int
). Учитывая формат вашего файла, чтение каждой строки данных с помощью функций семейства scanf
, вероятно, немного более разумно, чем чтение/токенизация каждой строки с помощью fgets/strtok
.
Ваше смешение синтаксиса fgets
и fscanf
не будет работать и иллюстрирует трудности при попытке сопоставить смешанные данные в строку формата . Вы должны позаботиться о том, чтобы обработать строку для обработки whitepace и любых завершающих строк новой строки, оставшихся во входном буфере. Для вашего набора данных, следующие будут работать так же, как и все остальное:
char *fmt = " %[^:]:%d:%d:%d:%d:%c";
Другой способ объяснить символ новой строки является использование присваивания подавления оператора читать и отбросить символ новой строки. При использовании отбрасываемая конверсия не добавляется к возвращенному счету . например
char *fmt = "%[^:]:%d:%d:%d:%d:%c%*c";
Нет необходимости в макросах, чтобы очистить входной буфер, если вы правильно создаете строку формата.
Ввод куски вместе, и выходя из запоздалое изменение от name
к last
, first
к вам, вы могли бы сделать что-то вроде следующего:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* constants for:
NGRDS - max number of grades per student.
MAXNM - max length of student name.
MAXSTD - max number of students in array.
MAXFN - max filename length.
*/
enum { NGRDS = 4, MAXNM = 26, MAXSTD = 45, MAXFN = 128 };
typedef struct {
char name[MAXNM];
int id;
int scores[NGRDS];
float ave;
char grade;
} student;
int main (void) {
char filename[MAXFN]; /* initialize variables */
char *fmt = " %[^:]:%d:%d:%d:%d:%c";
FILE* fp = NULL;
size_t i = 0, nstudents = 0;
student students[MAXSTD] = {{ {""}, 0, {0}, 0.0, 0 }};
printf ("\nEnter File Name: ");
if (scanf("%s", filename) != 1) { /* validate filename read */
fprintf (stderr, "error: invalid file name entered.\n");
return 1;
}
if (!(fp = fopen (filename, "r"))) { /* validate file open */
fprintf (stderr, "error: file open failed '%s'\n.", filename);
return 1;
}
/* read each line in file */
while (fscanf (fp, fmt, students[i].name, &students[i].scores[0],
&students[i].scores[1],&students[i].scores[2],
&students[i].scores[3], &students[i].grade) == 6) {
int j; /* compute sum/average */
for (j = 0; j < NGRDS; j++) students[i].ave += students[i].scores[j];
students[i].ave /= (float)NGRDS;
if (++i == MAXSTD) { /* check against max */
fprintf (stderr, "warning: students array full.\n");
break;
}
}
fclose (fp); /* close file */
nstudents = i; /* save number of students */
for (i = 0; i < nstudents; i++) { /* output student data */
size_t j;
printf ("\n Student[%2zu]\n name : %s\n scores :",
i, students[i].name);
for (j = 0; j < NGRDS; j++) printf (" %d", students[i].scores[j]);
printf ("\n average: %.2f\n grade : %c\n",
students[i].ave, students[i].grade);
}
return 0;
}
Пример данных
$cat dat/studentgrades.txt
Joe Cool:80:77:63:88:c
Nancy Smart:96:93:97:99:a
Dwane Dumb:61:60:67:50:f
Al Smith:75:77:78:73:c
Пример использования/вывода
$ ./bin/studentstruct
Enter File Name: dat/studentgrades.txt
Student[ 0]
name : Joe Cool
scores : 80 77 63 88
average: 77.00
grade : c
Student[ 1]
name : Nancy Smart
scores : 96 93 97 99
average: 96.25
grade : a
Student[ 2]
name : Dwane Dumb
scores : 61 60 67 50
average: 59.50
grade : f
Student[ 3]
name : Al Smith
scores : 75 77 78 73
average: 75.75
grade : c
(примечание: ваш класс письма должен быть рассчитан на основе среднего значения, а не просто читать из файла - что, если оценки меняются? Также обратите внимание, что формат входного файла является фиксированным и негибким. Если количество полей или их формат каким-либо образом изменяется, вы должны учитывать изменение в строке формата fmt
.)
Посмотрите и сообщите мне, если у вас есть вопросы.
«ожидаемое выражение перед токеном». ОК. Который. Линия. Находятся. . Ошибки. На. –
Макрос 'FFLUSH' нуждается в точке с запятой в конце, где вы ее используете – yano
мои извинения, строка 53. строка, которая просто имеет} под FFLUSH. – seanncurtis