2016-04-11 4 views
-3

*** ОБНОВЛЕНО С НОВЫМ КОДОМ Я пытаюсь загрузить данные файла с неизвестным количеством строк данных. Данные организованы как последние, во-первых: оценка 1: оценка 2: оценка 3: оценка5: lettergradeСтроки и массив структур

Я получаю файл для загрузки (массива) в массив и печать. Когда данные печатаются, он не печатает первое имя, просто первое. Он печатает одно и то же целое число для элемента данных evert, за исключением последнего, который выводится на 0 для всех. Кроме того, это не очистка данных, которые не возвращают 8 элементов. ПОЖАЛУЙСТА, помогите! Спасибо заранее.

#include <stdio.h> 
    #include <string.h> 
#include <stdlib.h> 
    #define FFLUSH while(fgetsc(fp) != '\n') 
    #define MAX_STUDENTS 45 

     typedef struct aStudent 
     { 
      char name[26]; 
      int id[7]; 
      int test1[4]; 
      int test2[4]; 
      int proj1[4]; 
      int proj2[4]; 
      int proj3[4]; 
      char grade[4]; 
     } aStudent; 

     int main(void) 
     { 

     char file_name[FILENAME_MAX]; 
     FILE* fp; 
     int i; 
     int rc; 
     int dc; 
     aStudent studentArray[MAX_STUDENTS]; 

     printf("Enter File Name: "); 
     rc = scanf("%s", &file_name); 
     if (rc == 0) 
     { 
      printf("\n\nError: No file name entered."); 
      exit(0); 
     } 

     fp = fopen(file_name, "r"); 

     if (fp == NULL) 
     { 
      printf("Error: Could not open file %s for read", file_name); 
      exit(0); 
     } 

      for(int i=0; i< 45; i++) 
      { 

      dc = (fscanf(fp, "%s[^:]%d[^:]%d[^:]%d[^:]%d[^:]%d[^:]%d[^:]%f[^:]%c[^:\n]", studentArray[i].name, studentArray[i].id, studentArray[i].test1, studentArray[i].test2, studentArray[i].proj1, studentArray[i].proj2, studentArray[i].proj3, studentArray[i].grade)); 

      if (dc != 8) 
      { 
       FFLUSH; 
      } 

       printf("%s %d %d %d %d %d %d %.2f %c", studentArray[i].name, studentArray[i].id, studentArray[i].test1, studentArray[i].test2, studentArray[i].proj1, studentArray[i].proj2, studentArray[i].proj3, studentArray[i].grade); 

     } 

     return 0; 
    } 
+0

«ожидаемое выражение перед токеном». ОК. Который. Линия. Находятся. . Ошибки. На. –

+0

Макрос 'FFLUSH' нуждается в точке с запятой в конце, где вы ее используете – yano

+0

мои извинения, строка 53. строка, которая просто имеет} под FFLUSH. – seanncurtis

ответ

1

СТУДЕНТ - это тип. Вы не можете входить в тип. Нет массива STUDENT. Попробуй это;

typedef struct aStudent 
{ 
    char name[26]; 
    int id[7]; 
    int test1[4]; 
    int test2[4]; 
    int proj1[4]; 
    int proj2[4]; 
    int proj3[4]; 
    int ave[4]; 
    char grade[4]; 
} aStudent; 

and;

aStudent studentArray[MAX_STUDENTS]; 

и заменить gGets на fscanf.

+0

Я думал, что создал структуру INSIDE в конце моей структуры, когда я говорю} STUDENT [MAX_STUDENTS]; – seanncurtis

+0

Я думаю, что у вас есть тип массива. Вы объявляете студентов «Студентов»; и вы получите массив [45] ....? –

+0

@MartinJames, не могли бы вы рассказать об этом больше, пожалуйста? Что значит получить массив [45]? – seanncurtis

0

похоже, что у вас неправильно настроена структура, чтобы обрабатывать данные, которые вы хотите прочитать из своего файла. Ваши данные были:

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.)

Посмотрите и сообщите мне, если у вас есть вопросы.

+0

im в настоящее время в другом классе сейчас, когда я возвращаюсь домой позже, я действительно надеюсь, что вы сможете ответить на вопросы! как я уже сказал, мне нужно написать этот код, но я действительно хочу знать, что я делаю. Коды копирования - это то, как учащиеся делают плохие оценки тестов. – seanncurtis

+0

Я буду рядом. У меня депо готовится завтра, поэтому я буду рад перерыву. –

+0

хорошо, поэтому я в основном вытащил код, который вы мне предоставили, и я понимаю, что большинство из этого ... намного больше, чем я ожидал на самом деле. благодарю вас за ярлык большого количества кода. – seanncurtis